次のように、EXIT
トラップを介して何らかのクリーンアップコードを実行するシェルスクリプトがあるとします。
#!/bin/bash
mytrap () {
echo "It's a trap!" >&2
}
trap mytrap exit
echo I am at the end of the script.
予想通り、これはIt's a trap!
スクリプトが終了したとき:
$ sh myscript
I am at the end of the script.
It's a trap!
次のように、スクリプトを変更して、最終的に別のコマンドにパイプ処理される出力を生成する関数を追加します。
#!/bin/bash
mytrap () {
echo "It's a trap!" >&2
}
myfunc () {
echo "I've got a bad feeling about this..."
}
trap mytrap exit
myfunc | cat > /dev/null
echo I am at the end of the script.
パイプがあるため、myfunc
のコードはサブシェルで実行されます...サブシェルは親のtrap
の動作を継承していないように見えます。つまり、ここでアクションを実行すると発生しないトラップコードでクリーンアップする必要があります。
だからあなたはこれを試してください:
myfunc () {
trap mytrap EXIT
echo "I've got a bad feeling about this..."
}
そして、それでもサブシェルが終了するときにmytrap
をトリガーできません。次のように、明示的なexit
が必要であることがわかります。
myfunc () {
trap mytrap EXIT
echo "I've got a bad feeling about this..."
exit
}
上記のコードでは、mytrap
はサブシェルの終了時に適切にトリガーされます。
$ sh myscript
It's a trap!
I am at the end of the script.
It's a trap!
それは予想される動作ですか?私はここでいくつかのことに驚いた:
trap
設定はサブシェルに継承されませんでしたEXIT
トラップをトリガーするようには見えません組み込みのbash trap
では、キーワードRETURN
を使用できます。したがって、変更:
trap mytrap EXIT
に:
trap mytrap RETURN
Shell-builtins のtrap
の説明を参照してください