trap
コマンドは「終了時」「エラー時」といったタイミングに処理したい事を設定できるコマンドです。例えば、シェルスクリプトの中で一時的ファイルを作成していて、最後にそれを忘れずに削除したいような場合に使うことがあります。
以下のコードは、「何十・何百行の処理」が終わった後にclean_files
関数が呼ばれ一時的なファイルが削除される、という例です。
clean_files() {
rm tempfile
}
trap 'clean_files' EXIT
# ...何十・何百行の処理
このEXIT
というのがフック対象の名前です。これには以下のものがあります。
EXIT
シェルスクリプト終了時ERR
エラーキャッチ時SIGHUP
ターミナルの切断SIGINT
ctrl + c
で中断された時SIGTERM
kill
される時
などがあります。3 つ目からはkill -l
で確認できるものが指定できます。
kill -l
# 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
# 5) SIGTRAP 6) SIGABRT 7) SIGEMT 8) SIGFPE
# 9) SIGKILL 10) SIGBUS 11) SIGSEGV 12) SIGSYS
# 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGURG
# 17) SIGSTOP 18) SIGTSTP 19) SIGCONT 20) SIGCHLD
# 21) SIGTTIN 22) SIGTTOU 23) SIGIO 24) SIGXCPU
# 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
# 29) SIGINFO 30) SIGUSR1 31) SIGUSR2
呼ばれる順番はSIG*
系の後、ERR
、EXIT
の順番で呼ばれます。
トラップのリセット
「ここに到達したらトラップを解除したい」という場合、trap - <trap_name>
を実行します。
trap - EXIT
ERR トラップ
ERR
は実行コマンドの終了ステータスが0
以外、または関数の終了ステータスが0
以外の時にっ呼ばれます。
以下のようなスクリプトではerror
と 2 回表示されます。②回
trap 'echo error' ERR
return_err() # 存在しないファイルを rm しようとする
{
m ... || r return 1
}
# 存在しないファイルを rm しようとする
rm ...
return_err
```ややこしいですが、`ERR`トラップは`EXIT`トラップのコマンドや関数が`0`以外の終了ステータスで終わった時にも呼ばれます。以下の場合も`error`と表示されます。
```bash
f() {
return 1
}
trap 'f' EXIT
trap 'echo error' ERR
同じ処理をするトラップ
フックしたい処理が同じならトラップを複数羅列することで、複数のタイミングで同じ処理ができます。
trap 'echo ...' SIGHUP SIGINT SIGTERM