プログラム作成にあたっては,ある箇所のエラーにより後続の処理が有害な挙動を起こしたりしないよう注意が必要だし,そもそもエラーが発生したらそれを確実に捕捉するようにすることが重要だ.シェルスクリプトでは set -e というエラー捕捉に便利な仕組みが利用できるが,無邪気に使うと痛い目に遭いそうだ.
#!/bin/sh
set -e
FUNC () {
false
}
FUNC
exit 0
# bottom of file
たとえばこれは,必ず失敗する false コマンドだけが入った関数 FUNC() を単に呼び出しているが,実行すると以下の通り.
$ ./func0.sh
$ echo $?
1
この結果は素直に受け容れられる.では次はどうか?
#!/bin/sh
set -e
FUNC () {
false
}
FUNC && printf "FUNC() succeeded.\n"
exit 0
# bottom of file
実行すると以下の通り.
$ ./func1.sh
$ echo $?
0
FUNC() が失敗して printf が実行されないのは期待通りだが,この行の実行が失敗 → 「set -e のはたらきで即 exit 1」とはなっていないことがわかる.これは,POSIX ドキュメントのこのあたりを読めば,「ああそういうこと」となるのだけども,直観的にそういう挙動を想像できるかというと,そうでもない.「このあたり」を抜粋しておく.
この他に,パイプライン中のコマンドの失敗では set -e 無効,while なんたらのあとのリストでは set -e 無効,サブシェルではない複文({} のことか)内のコマンドでは set -e 無効,が書かれている.