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

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

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 サブシェルの暗黙的なシャットダウンがトラップをトリガーしないようです。

答え1

bashtrap組み込みではキーワードを使用できますRETURN

trap mytrap EXIT

到着する:

trap mytrap RETURN

trapよりシェル組み込み関数

関連情報