シェルスクリプトのトラップ処理と暗黙のサブシェル


12

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

回答:


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.