next up previous contents
Next: シェルスクリプトのデバッグ Up: 実行制御 Previous: wait文

trap文

 

シェルスクリプトを書くときには実行中になんらかの原因で停止することも念頭に 置かなければなりません。停止する要因としてはユーザのDELキーよる割り込みとか、 異常終了、シグナル9が送られたとか、さまざまなものが考えられます。

この時にただちにシェルスクリプトを終了させてしまうとまずい場合があります。 例えば、一時作業ファイルを作って処理をしていて後始末をせずに終了して しまったのでは作業ファイルがディスクのゴミとして残ってしまいます。また、排他 制御のためのロックファイルを削除せずに終了したならば困ったことになります。 このような不都合を回避するために trap命令を使います。

trapはあるシグナルを受信した時になすべき仕事を指定するのに使い、書式 は次のようになっています。

trap command signal
commandは signalに指定されたシグナルリストのいずれかを受信したときに 実行されるコマンドです。 signalを受信したときに実行するコマンドが2つ以上の 場合にはそれらを引用符で囲まなければなりません。signalは一連の番号で表され、 minixで使われる主なものは次のようなものです。

 

次のリストは trap文を使って一時作業ファイルを削除し、スクリプトを終了 させる例です。

prog=`basename $0`
tmpfile="/tmp/$prog$$"
trap 'rm -f $tmpfile;exit 1' 2
any-command > $tmpfile
  
一時作業ファイル名には他のプロセスとの衝突を避けるためにプロセスIDを含めた ものが使われます。ここでもその慣例に従ってシェルスクリプト名とプロセスIDが 格納されているシェル変数 $$ で一時作業ファイルを作っています。 そして trap文です。ここではシグナル2を受け取ったときに 'rm $tmpfile;exit 1'が実行されるように設定します。なお、 trapの 設定は一時作業ファイルが作られる前に行なわなければ意味がありません。

シグナルを無視したい時には実行すべきコマンドを書く部分を引用符で囲んで「ヌル」 にします。

trap ' ' signal
しかし、「コマンドを書かなければ無視される」と早合点し trap文の第一引数 を省略して
trap signal
としてはいけません。このようにすると signalを受け付けたときの処理をデフォ ルトに再設定してしまいます。例えばシグナル2ならばシェルスクリプトを停止させる 標準処理を行ないます。

なお、ユーザがあるシグナルを無視するように設定すると、そこから起動される サブシェルも(シェルスクリプト)そのシグナルを無視します。 しかし、あるシグナルを受信したならば特定の処理を行うように設定した場合には、 その処理内容はサブシェル側にはいっさい伝わらず、該当シグナルに対して既定の 処理を行うだけです。



Riichiro Saito
1995年08月29日(火) 11時41分26秒 JST