trap ‘処理’ EXIT
以下の形式でtrap
コマンドを使用して、スクリプトの終了時に必ず実行される処理を設定できる。
trap '処理' EXIT
例えば、スクリプトの終了時にログを出力する場合は以下のように実行する。
trap 'echo "スクリプトが終了しました"' EXIT
# スクリプトの処理
echo "スクリプトの処理が完了しました"
実行すると、スクリプトの終了時に必ずスクリプトが終了しました
と表示される。
$ sh script.sh
スクリプトの処理が完了しました
スクリプトが終了しました
関数を定義して実行する
処理が長くなる場合は関数として定義すれば見通しが良くなる。
trap cleanup EXIT
function cleanup() {
echo "スクリプトが終了しました"
}
echo "スクリプトの処理が完了しました"
実行すると、スクリプトの終了時に必ずスクリプトが終了しました
と表示される。
$ sh script.sh
スクリプトの処理が完了しました
スクリプトが終了しました
エラーで途中終了した場合も実行される
trap
コマンドは、スクリプトがエラーで途中終了した場合でも実行される。
set -e
trap 'echo "スクリプトが終了しました"' EXIT
ls missing_file.txt # エラーを発生させる
echo "このメッセージは表示されません"
実行するとmissing_file.txt
は存在しないためエラーが発生。
スクリプトは途中で終了するものの、スクリプトが終了しました
は表示される。
$ sh script.sh
ls: cannot access 'missing_file.txt': No such file or directory
スクリプトが終了しました
trapが実行されない場合
trap
コマンドは強制的にプロセスを終了させる場合には実行されない。
trap 'echo "スクリプトが終了しました"' EXIT
sleep 60 &
PID=$!
echo "PID: $PID"
wait
以下のような場合、trap
による処理は実行されない:
kill -9
で強制終了した場合- システムクラッシュやハードウェア障害
- 電源切断など物理的な終了
その他のシグナル
trap
コマンドはEXIT
以外にも様々なシグナルを捕捉できる。
trap 'echo "Ctrl+Cで中断されました"' INT
trap 'echo "終了シグナルを受信しました"' TERM
trap 'echo "スクリプトが終了しました"' EXIT
sleep 60
それぞれのシグナルは以下のような状況で発生する。
- INT: Ctrl+Cを押したとき、割り込みシグナルが送信されたとき
- TERM:
kill
コマンドで終了シグナルが送信されたとき、システムシャットダウンとき - EXIT: スクリプトが終了するとき
\第一線のプログラマーの行動原理を学べる!/