53

私のbashコードには多くの出口点があります。出口でクリーンアップ作業を行う必要があるため、トラップを使用して、次のように出口のコールバックを追加しました。

trap "mycleanup" EXIT

問題は、さまざまな終了コードがあることです。対応するクリーンアップ作業を行う必要があります。mycleanupで終了コードを取得できますか?

4

4 に答える 4

70

受け入れられた答えは基本的に正しいです、私はただ物事を明確にしたいです。

次の例はうまく機能します。

#!/bin/bash

cleanup() {
    rv=$?
    rm -rf "$tmpdir"
    exit $rv
}

tmpdir="$(mktemp)"
trap "cleanup" EXIT
# Do things...

ただし、関数を使用せずにインラインでクリーンアップを実行する場合は、さらに注意する必要があります。たとえば、これは機能しません。

trap "rv=$?; rm -rf $tmpdir; exit $rv" EXIT

代わりに、変数$rv$?変数をエスケープする必要があります。

trap "rv=\$?; rm -rf $tmpdir; exit \$rv" EXIT

$tmpdirトラップラインが実行されたときに評価され、tmpdir後で値が変更された場合に期待される動作が得られない可能性があるため、エスケープすることもできます。

編集:shellcheckを使用してbashスクリプトをチェックし、このような問題に注意してください。

于 2014-05-13T17:30:27.177 に答える
53

$?終了コードを取得するために使用できると思います。

于 2011-03-15T13:32:56.577 に答える
9

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を削除する前に、その存在のテストを含めることもよくあります。そのため、スクリプトの開始時に設定する必要はなく、作成する前にのみ設定する必要があります。

于 2017-01-19T00:10:55.683 に答える
0

次のコードはうまく機能します。終了コードを保管し、トラップ関数の各終了コードに必要なコマンドを定義できます。

#!/bin/bash
trap cleanup EXIT
cleanup() {
   exit_code=$?
   if [[ ${exit_code} -eq 1 ]]; then
       # command 1
   elif [[ ${exit_code} -eq 2 ]]; then
       # command 2
   elif [[ ${exit_code} -eq 2 ]]; then
       # command 2
   fi
}
于 2022-01-20T10:39:40.650 に答える