4.3.1.The Set Builtin
https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#The-Set-Builtin
これを参照してbashスクリプトの冒頭でよく用いられるsetで使えるオプションを気の向くままにまとめる(つまり全部ではない、しかし必要なら上記に全部載っている)。
基本事項
bashのsetはシェルのオプションを設定するビルトインのコマンドとなっている。
インタラクティブシェルに関するオプションと、シェルスクリプトに関するオプションの両方をsetから操作する。前者はふつうにプロンプトで入力することが多く、後者はスクリプトの冒頭にかかれることが多い。
それぞれのオプションはアルファベット一文字からなるコードと、オプション名を表すアルファベット小文字数文字からなる短い名前を持っている。例えば
set -eux
とやるとこれは次と同一
set -o errexit # エラー時にスクリプトを終了する
set -o nounset # 未定義の変数を参照したらエラー出して終了する
set -o xtrace # 実行するコマンドを逐一表示する
もとに戻す場合は-
を+
にすればよい。
set +eux
例によってこれは次と同一
set +o errexit
set +o nounset
set +o xtrace
スクリプト内の変数や関数と同じようにsource
で呼び出している場合を除いて、set -eux
などによる設定はスクリプトが終了するともとに戻るため明示的に戻す必要はない(はず)。
今どのオプションが有効になっているかは特別な変数$-
に格納されている。
echo $-
例としてこの結果は以下
himBHs
特に何もせずにこの結果のため、これらのオプションはデフォルトでONになっているということだ。別な方法として以下がある。
set -o
とすると次のような出力でオプションの有効/無効がわかる。
allexport off
braceexpand on
emacs on
errexit off
errtrace off
functrace off
hashall on
histexpand on
history on
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
オプション
コードと短い名前を羅列してく。
allexport / a
変数と関数をすべてexport
扱いとする。すなわち、スクリプトが終了しても使用した変数や関数が環境に残る(環境変数)。
notify / b
主にインタラクティブシェル用。バックグラウンドジョブの状態を即座に画面に表示する(通常はユーザの入力を邪魔することが無いように、次のプロンプトが表示される直前に表示されている)。なぜb
かは不明。
errexit / e
いくつかの例外を除いて、コマンドが失敗を意味する非ゼロの終了コードを返したときにスクリプトを即座に終了する。
いくつかの例外となるコマンドを以下に示す。
while
/unitl
キーワードに続くコマンドif
キーワードとともに用いられるtest
コマンド&&
や||
によって最後以外に実行されるコマンド- パイプ
|
によって最後以外に実行されるコマンド - 終了状態が
!
によって反転されているコマンド
そのほかサブシェルとかに関して細かい挙動が書かれている。いったん省略。
nounset / u
未定義の変数を参照したときに、標準エラー出力に次のような表示をしてスクリプトを終了する(インタラクティブシェルの場合は終了しない)。
./test.sh: 5: a: parameter not set
このオプションが無効なときは未定義の変数を参照しても空の内容に展開されて不都合なければそのままスクリプトが進行する。実際には往々にして不都合の原因となるため、いっそスクリプトを止めてしまうというオプション。
ただし$@
や$*
など特殊なもの除く。$@
や$*
は位置引数$1
、$2
、$3
、、、をすべてを表す特殊な変数となっている。
xtrace / x
コマンドを実行する直前に、そのコマンドの内容を標準出力に表示する。直前なのでコマンドに含まれる変数などは展開された状態で表示される。
noexec / n
コマンドは読み込むが実際に実行しない。シェルスクリプトの構文が間違っていないかを確認するために用いられる。インタラクティブシェルにおいてこのオプションは無視される。
他人が作ったテスト中のスクリプトでこのオプションが入っていて動かせど動かせど何も起こらないといったミスがありそうなので注意が必要に思う。
noclobber / C
リダイレクトによって既に存在するファイルが上書きされる場合に標準エラー出力に次のようなメッセージを出す。
./test.sh: 5: cannot create test.log: File exists
>>
など追記する場合にはエラーは出さない。とにかく今あるファイルを上書きさせたくない場合はシェルスクリプトの冒頭でこのオプションを有効にしておくとよい(test -e
などで判定しなくてよい)。
いったんここまで。
余談
Windowsのcmdにおけるsetは環境変数の参照や設定のためのものだったが、bashのsetはシェルのオプション変更に加えていくつか異なる使い道を持っている。次のように--
のあとに引数を渡すとシェル上で定義されている位置引数$1
、$2
、、、を上書きする。
set -- first second third
このときecho $1
の結果は
first
となり、そのスクリプトの引数が上書きされていることがわかる。バッチファイルでもこういうことができるのかはわからないが、少なくともbashのsetにはこういう動作がある。
なお、cmdのsetと同じように
set
とすると環境にあるすべての変数/関数を画面に表示できる。cmdの場合と違って関数定義も変数のうちとして扱っているため、関数の中身まで表示されるためその出力行数が単純に多い。