トップ 差分 一覧 ソース 検索 ヘルプ RSS ログイン

技術的雑談-ctrl-cをscript内で捕捉する

技術的雑談-ctrl-cをscript内で捕捉する


 環境

GNU bash 2.05b(1)-release

 目的

  • スクリプト実行中にctrl+cを検出したい
  • どんな終わり方をしても必ず実行する処理を加えたい

 手段


trapコマンドを使います。

trapコマンドはshell script内でトラップが発生したときに実行したいscriptを設定するコマンドです。

書式


trap [-lp] [arg] [sigspec ...]

-l
signalの一覧を表示する
-p
指定したsignalに関連付けられているscriptを表示する
arg
sigspecに関連付けるscriptを文字列で記述する。空文字列を指定するとそのsignalの補足を解除できる。何も指定しないとそのsignalに現在関連付けられているscriptを表示する。
sigspec
スペース区切りでsignalを列挙する。

signal


ちなみに、よく使うsignalはこんな感じ。
文字列で指定しても数字で指定しても良い。

HUP (1)
kill -HUPなどで呼ばれる。普通は「設定ファイルの読み直し」を実装するのがお約束。
INT (2)
インタラプト。ctrl+cで発生する。
KILL (9)
プロセスの強制終了。INTよりも強い。kill -KILLで発行できる。これが来たらプログラムは直ちに終了するのがお約束。trapコマンドで何を書いても無視される。
TERM (15)
終了要求。trapで指定しても無視される。

使用例


#!/bin/sh

trap 'echo "HUP"' HUP
trap 'echo "INT"' INT
trap 'echo "KILL"' KILL
trap 'echo "TERM"' TERM
trap 'echo "zero"' 0

while [ $EEE -eq 0 ]
do
        echo '.'
        sleep 10
done

exit 0

10秒ごとに「.」を1つ表示します。
ctrl+cでもkill xxxxでも死にません。(ある意味危険ですな。)

ctrl+c押したりkill -HUPやったりkill -KILLすると「INT」「HUP」「KILL」なんて表示して、そのシグナルが来たことを教えてくれます。

止めたいときは、ctrl+zで一時中断してから、

ps

でこのscriptのPIDを調べて、

kill -TERM <PID>

で殺しましょう。

[1]+  Killed                  ./test.sh

とか出てきます。ちと怖い。

応用


manなんかをよく読むと、実行中のddにkill -ALRMとかやると今までに転送終わったデータ量とか表示してくれた気がするんだけど……linuxのmanには見当たらないなぁ…。

USR1とかUSR2などのユーザシグナルがあり、ユーザが独自のシグナルを定義するためにリザーブしてある。

ちなみに、Unixなどの「マルチプロセスOS」で一番手軽にプロセス空間を越えてメッセージを伝えるのが「シグナル」だったりする。
(いや、これを聞いて「おお〜」とか感心するのは、「メモリー空間」とか分かっていないと無理だよね(汗))

注意


trapでINTやKILLを捕捉するscriptを書いた場合、trap処理が不要になった時点で、

tarp '' INT

などと書いておかないとctrl+cで殺せないscriptになってしまう。

止められて困る場所を過ぎたらtrap解除するようにしましょう。
(ま、kill -TERMはユーザプロセスで補足不可能なsignalなので最終的にはそれで殺せるけど危ないでしょ?^^;)

 履歴

2005/10/06 -- 初版

技術的雑談へ戻る

 突っ込み

name   comment  
URL (入力するとす ぱ むとみなします!)


技術的雑談へ戻る

TrackBack

TrackBack URL for this entry:
http://www.himajin2001.com/fswiki/tb.cgi/%B5%BB%BD%D1%C5%AA%BB%A8%C3%CC%2Dctrl%2Dc%A4%F2script%C6%E2%A4%C7%CA%E1%C2%AA%A4%B9%A4%EB

技術的雑談へ戻る

最終更新日時:最終更新時間:2005年10月06日 18時02分21秒
トップページに戻る