私はBashスクリプトでエラーをキャッチし、発生した内容をログに出力するためにERRトラップを使用しています。 (この質問に似ています:トラップ、ERR、エコーエラーライン)期待通りに動作します。唯一の問題は、私のスクリプトのある時点で終了コード! = 0が発生すると予想されることです。この状況でトラップが機能するのをどのように防ぐことができますか?
以下はいくつかのコードです。
err_report() {
echo "errexit on line $(caller)" | tee -a $LOGFILE 1>&2
}
trap err_report ERR
次に、後でスクリプトで次のことを行います。
<some command which occasionally will return a non-zero exit code>
if [ $? -eq 0 ]; then
<handle stuff>
fi
コマンドがゼロ以外の値を返すたびに、マイトラップがトリガーされます。これを防ぐために、コードのこの部分をターゲットにすることはできますか?
この質問を確認しました。"set -eu"を使用した場合のEXITおよびERRトラップの正しい動作 しかし、私はこれを私の場合にどのように適用するのかわかりません。
答え1
エラーコードをすぐに「キャッチ」するとERR
trap
実行されません。できるif
常にエラー追跡機能をオンまたはオフにする代わりに、ステートメントなどを使用してください。しかし、あなたはできないフロー制御チェックを使用$?
すると、すでに(おそらく)キャッチされていないエラーがある可能性があります。
失敗すると予想されるコマンドがある場合 -欲しくないこれらの失敗トリガーを望むには、trap
単に失敗をキャッチするだけです。これをステートメントで囲むことはif
厄介で冗長ですが、次の略語はうまく機能します。
/bin/false || : # will not trigger an ERR trap
ただし、コマンドが失敗したときに操作を実行するには、if
次のようにします。
if ! /bin/false; then
echo "this was not caught by the trap!"
fi
または、else
エラー状態もキャプチャされます。
if /bin/false; then
: # dead code
else
echo "this was not caught by the trap!"
fi
要約すると、即時で本質的に説明されていないエラー条件がある場合にのみset -e
トリップが発生します。trap "command" ERR
答え2
ERR
必要に応じて、コードの一部でトラップを有効/無効にできます。
#!/bin/bash
err_report() {
echo "errexit on line $(caller)"
}
trap err_report ERR
trap - ERR # disable ERR trap
false
if [ $? -eq 0 ]; then
printf "OK\n"
else
printf "FAIL\n" # prints FAIL
fi
trap err_report ERR # enable ERR trap
false # prints errexit on line 14
答え3
私はしばしばERRトラップを避けたいのですが、関数の戻りコードを捨てたくありません。だから私が使用するパターンは次のとおりです。
RC=0
some_function || RC=$?
その後、RCを使用して必要なすべての操作を実行します。
答え4
このERR
トラップはと同じ規則に従いますset -e
。つまり、条件として使用されるコマンドには適用されません。だから、
trap "echo error" ERR
false # this should trigger the trap
if ! false; then # this shouldn't
echo handle stuff
fi
条件のコマンドは次のif
ようになります。どの必ずしもそうではないコマンドです[ .. ]
。したがって、コマンドの終了状態の真/偽の評価が必要な場合は、if
条件で直接使用できます。
終了コードを保存する必要がある場合そしてトラップを回避するには、ERR
次の作業を行う必要があります。
somecmd && :; ret=$?
ここではトラップは&&
圧縮されますが、ERR
終了コードが0の場合にのみ実行されるため、後続の終了コードが同じであることがわかります:
。
確認したいかもしれませんBashFAQ 105:-eを設定(または-o errexitまたはトラップERRを設定)しても、期待どおりに機能しないのはなぜですか?