処理の途中 Ctrl-C で中断するとき

実行中のスクリプトを、Ctrl-Cで終了させるとき、途中で要らなくなったテンポラリファイルを削除する等の、終了処理を実行させたいことが多々あります。このようなときは trap コマンドを使いましょう。

trapはとは、指定したシグナルを補足して、その後の処理を指定するためのコマンドです。
次の書式で使用することができます。

trap コマンド シグナルリスト

シグナルリストには、trapで補足したいシグナルの番号を書きましょう。
Ctrl-Cによって送られてくるシグナル(※)番号は2ですので、今回は、このシグナルリストには 2 を指定します。
コマンドには、実行したいコマンドやシェル関数名を書きます。

※シグナルとは何かについては、ここでは詳しく説明しませんが、とりあえず「何か実行中にCtrl-Cを押すと、実行中のプロセスに、番号2のシグナルが送られる」ということだけ覚えておいてください。

テスト用に、次のようなコードを用意しました。
このコードは、10秒間眠り、10秒後に0を返して終了する、という単純なコードです。
#!/bin/bash

# Ctrl-Cが押されたら、自動的に signalExit が呼ばれるようになる
trap signalExit 2

# signal受信時の終了処理
function signalExit() {
echo "signal recieved!"
exit 2
}

# 通常の終了処理
function normalExit() {
echo "ok."
exit 0
}

# 10秒間なにもしない
sleep 10

# 10秒後、正常終了
normalExit
このコードを trap_test.sh という名前で保存して、一度実行してみましょう。
10秒後に、ok. と表示されたと思います。

それでは、今度は実行中に、キーボードからCtrl-Cを押してみましょう。
signal recieved!
と表示されたと思います。

このようにすれば、Ctrl-Cで途中で処理を止めた時、定型処理を自動で実行させることができるようになります。

また、今回指定したtrapを解除したいときには、

trap 2

と、コマンド指定をせずにシグナル番号を指定してください。

シグナル番号9(SIGKILL)は、プロセスを強制終了させるためのシグナルですので、trapで補足することはできません。このシグナルを受信したプロセスは、直ちに終了してしまいますので、注意してください。

0 件のコメント: