次の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トラップをトリガーしていないように見える