次のコードでINTとERRの両方をトラップしています
set -ex -o pipefail
dest=$(mktemp -d)
cd "$dest"
trap "echo; echo Clean up; rm -rf $dest" INT ERR
sleep 9999
^C
を押すと、クリーンアップコールバックが複数回実行されます
++ echo Clean up
Clean up
++ rm -rf /tmp/tmp.KYXL110516
++ echo
++ echo Clean up
Clean up
++ rm -rf /tmp/tmp.KYXL110516
それは予想される動作ですか?一度だけ実行することはできますか?
bash
では、これをtrap "my-cleanup-command" EXIT
に置き換えるだけです。このトラップは、スクリプトがSIGINTで送信されたかどうかを含め、スクリプトが終了したときに実行されます。私の意見では、これは通常、よりエレガントなアプローチです...
それがbash固有であるという事実を除いて。 EXITトラップはPOSIXで言及されていますが、動作は指定されていません。他の多くのシェルでは、信号が原因でシェルが終了した場合、EXITトラップは実行されません。
https://unix.stackexchange.com/a/57960/2948
時々私はシェルスクリプトが本当に嫌いです:)。
リンクされた回答を見ると、最初のトラップの後にコードが実行されないようにするためのbash固有の方法は、すぐに終了することだと思います。これを行うにはさまざまな方法があるようですが、これが私が試す最も簡単な方法です。
cleanup() {
echo "Clean up"
rm -rf "$dest"
}
trap cleanup EXIT
trap "exit 1" INT ERR