誰かが以下のコードスニペットでbash / set -eの動作を説明できますか?
#!/bin/bash
# Comment if you want to test the trap only
set -e -o pipefail -u -E
# Comment if you want to test the set -e only
trap "echo ERROR CAUGHT; exit 12" ERR
function reproduce() {
# Trigger arithmetic error on purpose
a=$((1109962735 - hello=12272 + 1))
}
reproduce
# The script is expected to trigger the trap and/or activate the set -e. In both cases it should stop and exit here on error.
status_code=$?
echo "STATUS ${status_code}"
if [[ "${status_code}" != "0" ]];then
echo "FIXME: why was status code not caught by set -e ?"
echo "Executing false to prove set -e is still active"
false
# If the following is not executed then it proves -e is still active
echo "set -e not active !!!!!"
exit 2
fi
これを実行すると、次のようになります。
$ bash reproduce.sh
reproduce.sh: line 8: 1109962735 - hello=12272 + 1: attempted assignment to non-variable (error token is "=12272 + 1")
STATUS 1
FIXME: why was status code it not caught by set -e ?
Executing false to prove set -e is still active
ERROR CAUGHT
終了コードの確認
$ echo $?
1
バッシュバージョン
bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
と同様に再現
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
コメントに関する追加のメモ(とにかくすべての提案に感謝します):
- コメントトラップは、観察された奇妙な動作を変更しません
- トラップのみを保持するためにset -eを削除すると、トラップもトリガーされます
trap
代わりにメカニズムを使用するだけtrap "exit 2" ERR
です。また、私にとって、スクリプトは「ステータス0」のみを出力します。ERRトラップはシェル関数に継承されていないようですが、これは役立ちますset -o errtrace
か?それ以外の場合は、set -e
最初に避けなければならない理由について上記のリンクを参照してください。
set -e
とtrap
。trap
エラー時に呼び出され、「echo ERROR CAUGHT」が呼び出されます。trap
よりも優先順位が高い印象ですset -e
。またset -e
、推奨されないBash FAQによると 、mywiki.wooledge.org/BashFAQ/105を確認してください。