私のbashコードには多くの出口点があります。終了時にクリーンアップ作業を行う必要があるため、トラップを使用して、次のような終了用のコールバックを追加します。
trap "mycleanup" EXIT
問題は異なる終了コードがあり、対応するクリーンアップ作業を行う必要があることです。 mycleanupで終了コードを取得できますか?
$?
を使用して終了コードを取得できると思います。
受け入れられた答えは基本的に正しいです、私は物事を明確にしたいだけです。
次の例はうまく機能します。
#!/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
代わりに、$rv
および$?
変数をエスケープする必要があります。
trap "rv=\$?; rm -rf $tmpdir; exit \$rv" INT TERM EXIT
$tmpdir
をエスケープすることもできます。これは、トラップ行が実行されたときに評価され、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の存在をテストすることもよくあるので、スクリプトの開始時に設定する必要はなく、作成する前だけです。