set
とshopt
は両方とも、さまざまなオプションを制御するシェル組み込みです。どのオプションがどのコマンドによって設定され、どのオプションが設定/設定解除されるかを忘れてしまいがちです(set -o/+o
、shopt -s/-u
)。どうやら同じように見える(そしてそうするための引数が異なる)2つの異なるコマンドがあるのはなぜですか?どのオプションがどのコマンドに対応するかを覚える簡単な方法/ニーモニックはありますか?
私の知る限り、set -o
オプションは、他のBourneスタイルのシェル(主にksh)から継承されたものであり、shopt
オプションは、bashに固有のオプションです。私が知っているロジックはありません。
違いは、bashで使用される変更された環境変数にあります。 set
コマンドで設定すると、$SHELLOPTS
。 shopt
コマンドで設定すると、$BASHOPTS
。
set
はPOSIX 7です: set-設定または設定解除オプションと位置パラメーター| pubs.opengroup.org
shopt
ではない: Shell&Utilities:Detailed Toc | pubs.opengroup.org
おそらく@Gillesによって言及された歴史にリンクされています。
簡単ですが、歴史の中で失われました。 set
コマンドは、元のUNIXシェルのコマンドライン環境を変更するために最初に使用されました/bin/sh
。その後、さまざまなUnixバージョンが進化し、新しいシェルフレーバーが追加されたため、シェルスクリプトの互換性を維持するためには、さらに多くの(環境)変更が必要であることに人々は気づきました。当時、Bashは非常に人気があり、追加のshelloptions shopt
を導入する必要がありました。
これらのcompat互換性の試みは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
「Bashを使用したLinux Shell Scripting」の本の63ページから:
歴史的に、
set
コマンドはオプションのオンとオフを切り替えるために使用されていました。オプションの数が増えるにつれて、set
はオプションが1文字のコードで表されるため、使用がより困難になりました。その結果、Bashはshopt
(Shell option)コマンドを提供し、オプションを文字ではなく名前でオン/オフにします。一部のオプションは文字でのみ設定できます。その他はshopt
コマンドでのみ使用できます。これにより、特定のオプションを見つけて設定するのがややこしくなります。
「設定」オプションはサブシェルに継承され、ショップトは継承されないようです。
set
はボーンシェル(sh)に由来し、POSIX標準の一部ですが、shopt
はボーンシェルではなく、シェル(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
$