bashコードには多くの終了点があります。私はいくつかの終了時に仕事をクリーンアップ実行する必要があるので、私はこのように、出口のコールバックを追加するためにトラップを使用:Bashスクリプトで終了コードをトラップする方法
trap "mycleanup" EXIT
問題は別の終了コードがそこにいるですが、私はクリーンアップの作品を対応する実行する必要があります。 mycleanupで終了コードを取得できますか?
bashコードには多くの終了点があります。私はいくつかの終了時に仕事をクリーンアップ実行する必要があるので、私はこのように、出口のコールバックを追加するためにトラップを使用:Bashスクリプトで終了コードをトラップする方法
trap "mycleanup" EXIT
問題は別の終了コードがそこにいるですが、私はクリーンアップの作品を対応する実行する必要があります。 mycleanupで終了コードを取得できますか?
私は$?
を使用して終了コードを取得できると思います。
はい、正しいです。ありがとう! – Dagang
@Todd: '$ BASH_COMMAND'と' $ BASH_LINENO'変数は時には便利です。 –
@Todd、@bmk:実行された*コマンドが$?の値を変更することを忘れないでください。たとえば、myCmdIWantToTest;エコー$? ; myRC = $? ; ... myRCはエコー$の '真実'ですか? cmdが呼び出されます。 myCmdIWantToTestが「偽」を終了すると、その値は失われます。 $を保存するのが最善でしょうか?一意の別名varに変換します。 exitCode = $を使用していますか?普遍的に、他のcmdのexitCodeを継承することもできます(または、おそらくサブシェル(スクリプト)から継承することもできます)。また、ifの一部としてOKテスト終了コードであることを忘れないでください。その後、 ... fi。同様にmyCmdIWantToTest;エコーが働いた。そうでなければエコーは失敗したfi – shellter
受け入れられた答えは基本的に正しいです、私は物事を明確にしたいです。
#!/bin/bash
cleanup() {
rv=$?
rm -rf "$tmpdir"
exit $rv
}
tmpdir="$(mktemp)"
trap "cleanup" INT TERM EXIT
# Do things...
しかし、あなたはクリーンアップをインラインで行う場合は機能せず、より注意する必要があります:
次の例ではうまく動作します。たとえば、これは動作しません。
trap "rv=\$?; rm -rf $tmpdir; exit \$rv" INT TERM EXIT
あなたはまた、それが評価されますよう、
$tmpdir
を脱出したい場合があります
トラップライン:
trap "rv=$?; rm -rf $tmpdir; exit $rv" INT TERM EXIT
は、代わりにあなたが$rv
と$?
変数をエスケープする必要があります実行され、後でtmpdir
の値が変更された場合、期待される動作が得られません。
編集:shellcheckを使用してbashスクリプトを確認し、このような問題に注意してください。
は私が...それは他の信号
例トラップテストスクリプトのためのトラップとは別のEXITトラップに優れていることがわかりました
umask 77
tmpfile=`tmpfile.$$`
trap 'rm -f "$tmpfile"' EXIT
trap 'exit 2' HUP INT QUIT TERM
touch $tmpfile
read -r input
exit 10
の一時ファイルがクリーンアップされます。 ファイル終了値10が保持されます。 割り込みは2の終了値をもたらします
EXITトラップで「exit」を使用しない限り、元の終了値を保存して終了します。
ASIDE:EXITトラップの引用符に注意してください。これにより、スクリプトの存続期間中にどのファイルをクリーンアップする必要があるかを変更できます。私はしばしば、$ tmpfile varablesの存在に関するテストも含むので、スクリプトの最初に設定する必要はありません。
トラップ 'foo' EXITまたはトラップ 'foo' CHLD? –