Set 和 Shopt - 为什么是两个?

Kev*_*vin 89 bash settings shopt

set和shopt都是控制各种选项的 shell 内置函数。我经常忘记哪个命令设置了哪些选项,以及设置/取消设置了哪些选项 ( set -o/+o, shopt -s/-u)。为什么有两个不同的命令看似做同样的事情(并且有不同的参数)?有什么简单的方法/助记符可以记住哪个选项与哪个命令一起使用?

Gil*_*il' 48

据我所知,这些set -o选项是从其他 Bourne 风格的 shell(主要是 ksh)继承而来的,而这些shopt选项是特定于 bash 的。没有我知道的逻辑。

  • 好吧,有一些像 `posix`/`physical`/`interactive-comments` 这样的 `set -o` 选项不在 `ksh` 中,还有 `shopt` 选项在其他 shell 中,包括 `ksh` 中的一些类似 ` login_shell`/`nullglob`。就像你说的,没有逻辑。这可能是一开始的想法(SHELLOPTS 将是标准的,而 BASHOPTS 是 bash 特定的),但在此过程中迷失了方向,现在它最终变得很烦人,并且是 UI 设计的失败。 (9认同)

mug*_*896 27

不同之处在于 bash 使用的已更改环境变量。使用set命令进行设置会导致$SHELLOPTS. 使用shopt命令进行设置会导致$BASHOPTS.

  • 啊! 那更令人困惑。我的大脑想将 `shopt` 与 $ **SH**ELL**OPT**S 而不是 $ BA**SHOPT**S 联系起来。 (14认同)

emi*_*nix 12

容易,但在历史中迷失了。该set命令最初用于修改原始 unix shell 的命令行环境/bin/sh。然后随着各种 Unix 版本的发展和新的 shell 风格的加入,人们意识到他们需要能够改变更多(环境)的东西,以保持 shell 脚本兼容。当时猛砸变得非常流行和附加SH ELL选择需要离子导入shopt。

您实际上可以在命令中看到这些兼容性尝试shopt。

$ shopt
autocd          off
cdable_vars     off
cdspell         off
checkhash       off
checkjobs       off
checkwinsize    off
cmdhist         on
compat31        off
compat32        off
compat40        off
compat41        off
compat42        off
complete_fullquote      on
direxpand       off
dirspell        off
dotglob         off
execfail        off
expand_aliases  on
extdebug        off
extglob         off
extquote        on
failglob        off
force_fignore   on
globstar        off
globasciiranges off
gnu_errfmt      off
histappend      on
histreedit      off
histverify      off
hostcomplete    on
huponexit       off
interactive_comments    on
lastpipe        off
lithist         off
login_shell     on
mailwarn        off
no_empty_cmd_completion off
nocaseglob      on
nocasematch     off
nullglob        off
progcomp        on
promptvars      on
restricted_shell        off
shift_verbose   off
sourcepath      on
xpg_echo        off
Run Code Online (Sandbox Code Playgroud)

但不在set命令中。

$ set -o
allexport       off
braceexpand     on
emacs           on
errexit         off
errtrace        off
functrace       off
hashall         on
histexpand      on
history         on
igncr           off
ignoreeof       off
interactive-comments    on
keyword         off
monitor         on
noclobber       off
noexec          off
noglob          off
nolog           off
notify          off
nounset         off
onecmd          off
physical        off
pipefail        off
posix           off
privileged      off
verbose         off
vi              off
xtrace          off
Run Code Online (Sandbox Code Playgroud)

  • `set` 作为设置选项的一种方式不在最初的 Unix shell 中,它是由 Bourne shell 在 70 年代后期引入的。`set -o name` 本身是后来由 Korn shell 添加的,在 POSIX 中指定但可选,仍然不受 _“现代”_ 版本的 Bourne shell 支持,例如 Solaris 10 的 `/bin/sh`。 (3认同)

LoM*_*aPh 8

来自“Linux Shell Scripting with Bash”一书,第 63 页:

历史上,该set命令用于打开和关闭选项。随着选项数量的增加,set变得更加难以使用,因为选项由单字母代码表示。因此,Bash 提供了shopt( shell option ) 命令来按名称而不是字母来打开和关闭选项。您只能通过字母设置某些选项。其他仅在shopt命令下可用。这使得查找和设置特定选项成为一项令人困惑的任务。

  • `shopt` 不应该包含所有 `set` 变量吗?这样,新脚本可以使用“shopt”,并且将保留“set”以实现兼容性。 (5认同)