終了トラップのあるスクリプトからのシェルエラーが発生した場合に、呼び出し元に終了コードを伝達する
質問
EXIT トラップを使用した Bash スクリプトで構文エラーが発生した場合に、呼び出し元に終了コードを伝播することは可能ですか?たとえば、次のものがあるとします。
#! /bin/bash
set -eu
trap "echo dying!!" EXIT
echo yeah
echo $UNBOUND_VARIABLE
echo boo
その後、スクリプトが実際には正常に終了しなかった場合でも、実行すると終了コード 0 が返されます。
$ bash test.sh
yeah
test.sh: line 8: UNBOUND_VARIABLE: unbound variable
dying!!
$ echo $?
0
ただし、終了トラップをコメントアウトすると、スクリプトは 1 を返します。あるいは、非バインド変数を含む行をゼロ以外を返すコマンドで置き換えると(例: /bin/false
)、その終了値は希望どおりに伝播されます。
解決 2
この動作は、Bash の異なるバージョンに関連しています。元のスクリプトは Bash 4.2 では期待どおりに動作しますが、3.2 では動作しません。エラーが発生しやすいコードを別のスクリプト ファイルに記述し、サブシェルで実行すると、以前の Bash バージョンの問題が回避されます。
#!/bin/bash
$BASH sub.sh
RETVAL=$?
if [[ "$RETVAL" != "0" ]]; then
echo "Dying!! Exit code: $RETVAL"
fi
サブ.sh:
set -eu
echo yeah
echo $UNBOUND_VARIABLE
echo boo
他のヒント
シェルは、最後に実行されたコマンドの結果を表示して終了します。あなたの罠の場合、それは echo
, 、通常は成功で返されます。
自分の価値を広めるには、次のようにします。 exit
それと。
#!/bin/bash
set -eu
die() {
echo "Dying!!"
exit "$1"
}
trap 'die $?' EXIT
echo yeah
echo $unbound
echo boo
また、次の点にも注意してください set -e
これは有害であると考えられています。コマンドが失敗するとスクリプトが終了すると思わせますが、常に終了するとは限りません。
所属していません StackOverflow