set -e の罠

image_printPrintable Format

プログラム作成にあたっては,ある箇所のエラーにより後続の処理が有害な挙動を起こしたりしないよう注意が必要だし,そもそもエラーが発生したらそれを確実に捕捉するようにすることが重要だ.シェルスクリプトでは 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 ドキュメントこのあたりを読めば,「ああそういうこと」となるのだけども,直観的にそういう挙動を想像できるかというと,そうでもない.「このあたり」を抜粋しておく.

2. The -e setting shall be ignored when executing the compound list following the whileuntilif, or elif reserved word, a pipeline beginning with the ! reserved word, or any command of an AND-OR list other than the last.

このあたり より

この他に,パイプライン中のコマンドの失敗では set -e 無効,while なんたらのあとのリストでは set -e 無効,サブシェルではない複文({} のことか)内のコマンドでは set -e 無効,が書かれている.

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です