Linuxシェルスクリプトでプロセスの終了や中断に柔軟に対応したい場面は少なくありません。たとえば、ユーザーがCtrl+Cを押してスクリプトを終了させたときに一時ファイルを削除したい、プロセスが強制終了されたときにログを記録したいといったケースです。そんなときに役立つのが trap
コマンドです。trapコマンドを使えば、特定のシグナル(終了、割り込みなど)をキャッチして、独自の処理を定義できます。この記事では、trapコマンドの基本的な使い方から、実践的なスクリプト例までを詳しく解説します。シェルスクリプトを安全かつ柔軟に運用するための知識として、ぜひこの機会にtrapの使い方をマスターしてみてください。
trapコマンドは、BashやshなどのUnix系シェルで使える組み込みコマンドの1つです。特定のシグナル(例:SIGINT
, SIGTERM
, EXIT
など)を受け取ったときに、任意の処理を実行するように設定できます。通常のスクリプトでは、予期しない中断が起こるとそのまま異常終了してしまいますが、trapを使えば、終了処理を行ったり、ログを記録したりすることができます。
trap 'コマンド群' シグナル
たとえば、以下のように記述すると、Ctrl+C(SIGINT)を押した際に「割り込みを検知しました」と表示されます。
trap 'echo "割り込みを検知しました"' INT
シグナルとは、プロセスに対して送る通知のようなもので、プロセスの制御に使われます。trapで扱う代表的なシグナルは以下の通りです。
シグナル | 説明 |
---|---|
INT | 割り込み(Ctrl+C) |
TERM | 終了要求 |
HUP | ハングアップ(端末切断など) |
EXIT | スクリプトの終了時 |
ERR | コマンド失敗時(set -e 使用時) |
QUIT | コアダンプ付きの終了(Ctrl+\) |
これらをtrapでキャッチして、任意の処理を定義できます。
以下に、trapコマンドの書き方と基本的な使用例を紹介します。
#!/bin/bash
TEMP_FILE="/tmp/my_tempfile"
# 一時ファイル作成
touch $TEMP_FILE
echo "一時ファイルを作成しました:$TEMP_FILE"
# trapで終了処理を設定
trap 'echo "終了処理中..."; rm -f $TEMP_FILE; echo "一時ファイルを削除しました"; exit' EXIT
# 無限ループ(終了まで何か作業)
while true; do
echo "作業中... Ctrl+Cで終了"
sleep 2
done
このスクリプトでは、スクリプトが終了するタイミング(正常終了、Ctrl+Cなど)で一時ファイルを削除する処理をtrapで定義しています。
trapでは、複数のシグナルに同じ処理を割り当てることも可能です。
trap 'echo "終了または割り込みを検知"; cleanup' INT TERM
この例では、INT
(Ctrl+C)とTERM
(終了要求)のどちらかが来たときに、cleanup
関数を実行するようにしています。
trapでは処理内容に関数を使うこともできます。スクリプトが長くなる場合や、処理を複数まとめたいときに便利です。
bashコピーする編集するcleanup() {
echo "クリーンアップ処理中..."
rm -f /tmp/tempfile
echo "完了しました"
}
trap cleanup EXIT
このように、処理を関数化することで、可読性や保守性が向上します。
以下は、ログファイルに処理結果を書きつつ、一時ファイルを削除して終了する例です。
#!/bin/bash
LOGFILE="/tmp/script.log"
TEMPFILE="/tmp/tempfile.txt"
touch "$TEMPFILE"
echo "作業開始" >> "$LOGFILE"
trap '{
echo "終了時刻: $(date)" >> "$LOGFILE"
echo "一時ファイルを削除します" >> "$LOGFILE"
rm -f "$TEMPFILE"
echo "終了しました"
}' EXIT
echo "スクリプト実行中..." >> "$LOGFILE"
sleep 10
このスクリプトでは、スクリプトが終了する際に、ログを記録しつつファイルの削除を行っています。システム運用やサーバー管理においてよくある実装です。
一度設定したtrapを解除するには、以下のように記述します。
trap - シグナル
もしくは、すべてのtrapを解除したいときは以下のようにします。
trap - EXIT INT TERM
これで、それ以降のシグナルに対するtrapの影響が無効になります。
trapを使う際の注意点もいくつかあります。
trap
は現在のシェルプロセスにのみ有効です。subshell
(括弧で囲った処理)では反映されないことに注意しましょう。trap '...' int
のように小文字で書くと動作しないことがあります。INT
やTERM
のように大文字で書くのが正解です。while
やfor
ループ内でtrap
したとき、適切にexit
しないと処理が終わらないことがあるので、明示的に終了するようにしましょう。trapコマンドは、シェルスクリプトにおけるエラーハンドリングやリソースのクリーンアップに欠かせない重要なツールです。予期しない中断や異常終了からスクリプトを守るために、ぜひ積極的に活用してみてください。基本的な使い方から、関数化、ログ処理まで、状況に応じてtrapをうまく使い分ければ、より堅牢で実用的なスクリプトを書くことができるようになります。