设置和购物-为什么要两个?


72

set并且shopt都是控制各种选项的shell内置程序。我经常忘记由哪个命令设置哪些选项,以及设置/取消设置哪些选项(set -o/+oshopt -s/-u)。为什么会有两个不同的命令看似执行相同的操作(并且具有不同的参数来执行此操作)?有什么简单的方法/助记符来记住哪个选项与哪个命令一起使用?


6
尝试查看的第二行,help sethelp shopt验证甚至他们的作者也认为他们做同样的事情。
l0b0

2
“更改外壳程序属性的值”与“更改每个外壳程序选项的设置”。
凯文

2
在Bash 4.1.5(1)-release中,它说“设置或取消设置Shell选项和位置参数的值”。和“设置和取消设置外壳程序选项”。
l0b0

编写联机帮助页使您意识到自己不知道的内容,并使您尝试以对所尝试撰写的内容不正确的方式来制定事物。
sjas

Answers:


40

据我所知,set -o选项是从其他Bourne样式的shell(主要是ksh)继承的shopt选项,而这些选项是bash特有的选项。我没有逻辑可言。


1
显示的任何文档shopt都是继承的吗?
费利佩·阿尔瓦雷斯

8
好吧,有些set -oposix/ physical/的选项interactive-comments不在in中ksh,而有些shopt则在其他shell中,包括kshlogin_shell/这样的nullglob。就像你说的那样,没有逻辑。最初可能是想法(SHELLOPTS是标准的,BASHOPTS是bash的特定想法),但是一路迷失了,现在最终变得烦人,UI设计惨败。
斯特凡Chazelas

22

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


9
啊! 这更令人困惑。我的脑袋要关联shopt与$ SH ELL OPT做得相当超过$ BA 禁用了javascript S.
布鲁诺Bronosky


8

容易,但历史悠久。该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

但是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

2
set作为设置选项的方法不是最初的Unix shell所采用,它是Bourne shell在70年代后期引入的。set -o name本身是后来由Korn shell添加的,在POSIX中已指定但是可选的,但仍不受Bourne shell 的“现代”版本(如/bin/shSolaris 10)的支持。
StéphaneChazelas,2016年

5

摘自《带Bash的Linux Shell脚本》,第63页:

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


3

看起来“设置”选项是由子Shell继承的,而Shopt则不是。


不错的收获。我想知道这是故意选择还是副作用。
凯文

2
@至少下user29778 的bash 4.1.5(1)与设置的选项set不被subshel​​ls.Both继承setshopt选项不是由子shell继承。
马丁

你能指出来描述两者的传承特点的文档setshopt
费利佩·阿尔瓦雷斯

9
这两个set -oshopt选项由子shell(继承(...)$(...),管道元件)。无论他们是通过其他遗传bash调用取决于是否SHELLOPTS或者BASHOPTS在环境中或不是。
斯特凡Chazelas

0

set源于bourne shell(sh),是POSIX标准的一部分,shopt但是不是,并且是bourne-again shell(bash)特定的:

0 sjas@ssg 14:31:45 ~  
set | grep -e SHELLOPTS -e BASHOPTS
BASHOPTS=checkwinsize:cmdhist:complete_fullquote:dotglob:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:progcomp:promptvars:sourcepath
SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor

0 sjas@ssg 14:31:51 ~  
shopt | column -t | grep -v off
checkwinsize             on
cmdhist                  on
complete_fullquote       on
dotglob                  on
expand_aliases           on
extglob                  on
extquote                 on
force_fignore            on
histappend               on
interactive_comments     on
progcomp                 on
promptvars               on
sourcepath               on

0 sjas@ssg 14:31:57 ~  
set -o | column -t | grep -v off
braceexpand           on
emacs                 on
hashall               on
histexpand            on
history               on
interactive-comments  on
monitor               on

0 sjas@ssg 14:37:41 ~ 
sh 

$ set -o
Current option settings
errexit         off
noglob          off
ignoreeof       off
interactive     on
monitor         on
noexec          off
stdin           on
xtrace          off
verbose         off
vi              off
emacs           off
noclobber       off
allexport       off
notify          off
nounset         off
priv            off
nolog           off
debug           off

$ shopt
sh: 3: shopt: not found

$ 
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.