お兄ちゃん!
一時ファイルを作るスクリプトを
Ctrl + C で止めると
一時ファイルが残っちゃうよ!
スクリプトの最後の後処理で
一時ファイルを削除しているので
途中で止めたら残るのは
仕方ないとは思うけど…
なんとかならないかな?
2
)」trap
コマンドtrap
は
シグナルの処理を定義するよ
trap ['コマンド'] シグナル番号...
シェルが指定された
シグナル番号
を受け取ったらコマンド
を実行してくれるんだtrap
の シグナル番号
に2
を指定すればCtrl + C で止められたときの処理を指定できるんだね!trap
では特別なシグナル番号 0
を指定できるんだこれは0
番はよく使いそうだね他に気をつけるシグナルはあるかな?強制終了を表す「SIGKILL( は 処理できないんだ
9
)」trap
で 9
番を指定してもコマンド
は実行されず実行されているスクリプトは即時終了になるよ一度
trap
を設定すると解除できないのかな?コマンドを省略すると
trap
をの設定を解除するよ以下はシグナル番号 2
のtarp
の設定を解除するんだtrap 2
指定するコマンドを空文字にするとそのシグナルに対して「何もしない」という 指定ができるよつまり指定されたシグナルを無視する動作になるんだ
以下は SIGHUP(
1
) を無視する設定だよtrap '' 1
nohup
と同じ挙動になるんだね!シグナルのではシグナルが送信されても一時ファイルが後片付けされるようなスクリプトを書いてみよう!
#!/bin/bash
# シグナル処理定義
function cleanup() {
[ -e "$TEMP_FILE" ] && rm -rf "$TEMP_FILE"
exit "$1"
}
# シグナル処理設定
trap 'cleanup 0' 0
trap 'cleanup 1' 1 2 3 15
# 一時ファイル作成
TEMP_FILE="$(mktemp "/tmp/${0##*/}.XXXXXXXX")"
# 一時ファイルを使う処理
...
このスクリプトではシグナルを以下のように処理しているよ
シグナル名 | シグナル番号 | 意味 | 終了ステータス |
---|---|---|---|
- | 0 | シェルスクリプト終了 | 0 |
SIGHUP | 1 | 端末の接続切れを通知 | 1 |
SIGINT | 2 | キーボード割り込み(Ctrl + C) | 1 |
SIGQUIT | 3 | キーボード中止(Ctrl + /) | 1 |
SIGTERM | 15 | 終了 | 1 |
これまで一番最後にあった一時ファイルの後処理は書かなくてもいいんだね!
シェルスクリプト終了時に
0
番のシグナルが送られるからねtrap
で 0
番を処理すると決めておくと書かなくても良くなるんだcleanup
関数を定義しているみたいだけど?trap
で指定する コマンド
は1行である必要があるんだこの コマンド
を関数にしてあげることで複数行の処理を書けるようになるんだtrap
でよく使われる書き方だよ!今回はシェルスクリプトでシグナルを扱う方法を学んだよ!
trap
を使って定義してあげるんだね!trap
が実行されてからシグナルを扱えるようになるんだなのでなるべくスクリプトの冒頭で実行してあげるようにしよう!