BASH:トラップの終了状態の変更

BASH:トラップの終了状態の変更

トラップハンドラのシェルスクリプトに別の終了ステータスを指定できますか?

試行錯誤を経て通話終了exit状態trapが変更されることがあることを発見しました。通常のコマンドは、失敗しても成功しても終了ステータスを変更しません。

これで、この動作を信頼できるのか、それとも実装に問題があるのか​​疑問に思います。

これに関する文書を見つけようとしましたが、役に立ちませんでした。

テストスクリプト:

#!/bin/bash
function handler {
    # a successful command won't change script exit status
    echo handler, status=$1
    # badcommand won't change script exit status
    #badcommand
    # exit will change script exit status
    #exit 23
}
trap 'handler $?' EXIT
#badcommand

使用法:

./trap_test.sh; echo status_out=$?

答え1

トラップを呼び出して終了ステータスを変更できることを発見しましたexit。通常のコマンドは、失敗しても成功しても終了ステータスを変更しません。これで、この動作を信頼できるのか、それとも実装に問題があるのか​​疑問に思います。

はい、信頼でき、シェルに文書化されています。基準:

name
exit- シェルを終了します
...
説明
...
トラップは、EXITシェルが終了する前に実行する必要があります。exitユーティリティがトラップ自体内で呼び出されない限り、この場合、シェルはすぐに終了する必要があります。
...
終了状態指定した場合、
終了状態は次のようになりますが、符号なし10進整数以上でない限り、動作はn指定されません。そうでない場合、値は最後に実行されたコマンドの終了値でなければならず、コマンドが実行されていない場合はゼロでなければなりません。n255トラップジョブ内で実行される場合、exit最後のコマンドはトラップジョブの直前に実行されたコマンドと見なされます。

(同じことreturn

exitコマンドはありませんが、exitトラップが設定されている場合は、以下を適用する必要があります。

特に明記しない限り、コマンドの終了ステータスは、そのコマンドによって実行された最後の単純コマンドの終了ステータスです。

複合コマンド、順次リストなどに関するすべてのルールと同様に、これらのルールにはEXITトラップの存在に関する特別な例外はありません。

答え2

マニュアルページにはこれについて言及していないので、コードを見ることに加えて実験を試すことが何が起こるのかを見つけるための最良の方法のようです。

終了トラップが常に終了ステータスを変更するわけではないことがわかります。スクリプトはトラップを介してシャットダウン時にいくつかのクリーンアップを実行しようとしますが、デフォルトのスクリプトで設定されたシャットダウン状態でクリーンアップがめちゃくちゃになることはありません。そして、あなたが言ったようにトラップをexitやり直すことによってあなたが望む値を設定することができます。

たとえば、次のような場合があります。

tmpfile=$(mktemp)
trap 'rm -f "$tmpfile"' EXIT
# something
exit 1

終了状態をゼロにリセットすることもできますが、rmこれはあまり良いことではないようです。

関連情報