この記事では、Unixのシグナルとトラップについて詳しく説明します。
シグナルは、重要なイベントが発生したことを示すために、プログラムに送信されるソフトウェアが中断されます。 イベントは異なるかもしれません。ユーザーの要求から不正なメモリアクセスエラーまでです。 あるシグナル(割り込みシグナルなど)は、ユーザーがプログラムに通常の制御フローの一部ではない操作を実行するように要求したことを示します。
次の表には、プログラムで使用可能のシグナルを示します。
シグナル名 | シグナル番号 | 説明 |
SIGHUP | 1 | 制御端末を切断するか、制御プロセスを終了します。 |
SIGINT | 2 | ユーザーが割り込みシグナル(Ctrl + C)を送信すれば、発信します。 |
SIGQUIT | 3 | ユーザーが終了シグナル(Ctrl + D)を送信すれば、発信します。 |
SIGFPE | 8 | 不正なオペランドが試みられた場合、送信します。 |
SIGKILL | 9 | プロセスがこのシグナルを受信した場合、プロセスはすぐに終了する必要があり、クリーンアップ操作は実行されません。 |
SIGALRM | 14 | 時計シグナルです。(タイマー用) |
SIGTERM | 15 | ソフトウェア終了シグナルです。(デフォルトで送信を終了します) |
目次
シグナルリスト
システムでサポートされているすべての信号を一覧表示する簡単な方法があります。 kill -l
コマンドを発行するだけで、サポートされているすべてのシグナルが表示されます。
$ kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT
17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU
25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH
29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN
35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4
39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12
47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14
51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10
55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6
59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
シグナルの実際のリストは、Solaris、HP-UX、およびLinuxと異なります。
デフォルトの操作
各シグナルには、デフォルトの操作が関連付けられています。 シグナルのデフォルトの操作は、シグナルが受信された場合、スクリプトまたはプログラムによって実行される操作です。
デフォルトの操作は次のとおりです。
- プロセスを終了します。
- シグナルを無視します。
- コアをダンプします。 これにより、シグナルが受信された場合、プロセスのメモリイメージを含むcoreと呼ばれるファイルが作成されます。
- プロセスを終了します。
- 終了したプロセスを続行します。
シグナルを送信する
プログラムまたはスクリプトにシグナルを渡す方法はいくつかあります。 よく見えるのは、ユーザーがスクリプトの実行中にCONTROL-C
またはINTERRUPT
キーを入力することです。
Ctrl + C
を押すと、SIGINT
がスクリプトに送信され、定義されたデフォルトの操作に従ってスクリプトが終了します。
シグナルを送信するもう1つの一般的な方法は、kill
コマンドを使用することです。構文は次のとおりです。
$ kill -signal pid
ここで、signal
は配信されるシグナルの番号または名前であり、pid
はシグナルの送信先となるプロセスIDです。 例えば、
$ kill -1 1001
上記のコマンドは、プロセスID1001で実行されているプログラムにHUPまたはハングアップシグナルを送信します。 同じプロセスに終了シグナルを送信するには、次のコマンドを使用します-
$ kill -9 1001
これにより、プロセスID1001で実行されているプロセスが終了します。
トラップシグナル
シェル(Shell)プログラムの実行中に端末でCtrl + CまたはBreakキーを押すと、プログラムは通常すぐに終了し、コマンドプロンプトに戻ります。 これはいい結果ではありません。 例えば、クリアできない一時ファイルが大量に発生する可能性があります。
これらのシグナルをキャッチするのは非常に簡単で、trapコマンドの構文は次のとおりです。
$ trap commands signals
ここでのコマンドは、ユーザー定義関数を含め、任意の有効なUnixコマンドにすることができ、signalは、キャプチャする任意の数のシグナルのリストにすることができます。
シェルスクリプトでのトラップの常用の使い方は2つあります。
- 一時ファイルをクリーンアップします。
- シグナルを無視します。
一時ファイルをクリーンアップする
以下のはトラップコマンドの実例であり、特定のファイルを削除し、誰かが端末からプログラムを中止する場合に終了する方法を示しています。
$ trap "rm -f $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 2
シェル(shell)プログラムでトラップが実行されてから*、プログラムがシグナル番号2を受信すると、work1 $$*と*dataout $$*の2つのファイルが自動的に削除されます。
これにより、このトラップの実行後にユーザーがプログラムの実行を中断した場合、これら2つのファイルが確実にクリアされます。 rmがない場合は、シグナルを受信して停止するまでプログラム内で実行を継続するため、rmに続くexitコマンドが必要です。
シグナル1を生成して切断します。 誰かが回線を切断したか、誤って回線が切断されました。
シグナルリストにシグナル1を追加して前のトラップを変更し、この場合は指定された2つのファイルも削除できます。
$ trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2
回線を切断するかCtrl + Cを押すと、これらのファイルは削除されます。
指定されたTrapコマンドに複数のコマンドが含まれている場合は、引用符で囲む必要があります。 また、Trapコマンドが実行されたとき、およびリストされたシグナルの1つが受信された場合、shellがコマンドラインをスキャンすることにも注意してください。
これにより、前の実例では、Trapコマンドが実行されるとWORKDIRと$$の値が置き換えられます。 シグナル1または2を受信し、この置換を行う場合、コマンドを一重引用符で囲むことができます。
$ trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2
シグナルを無視する
リストされているトラップコマンドが空の場合、指定されたシグナルを受信し、シグナルは無視されます。 例えば、コマンド
$ trap '' 2
これは、割り込みシグナルが無視されることを指定します。 中断したくない操作を実行する場合、特定のシグナルを無視したい場合があります。 次のように、無視する複数のシグナルを指定できます。
$ trap '' 1 2 3 15
シグナルを無視するには最初のパラメータを指定する必要があることに注意してください。これは、次のパラメータ(独自の意味を持つ)を記述することと同じではありません。
$ trap 2
シグナルが無視されると、すべてのサブShellプログラムもシグナルを無視します。 ただし、シグナルの受信時に実行するアクションを指定した場合でも、シグナルの受信時にすべてのサブShellプログラムがデフォルトの操作を実行します。
Trapをリセットする
シグナルを受信した後に実行するデフォルトの操作を変更した後、最初のパラメータを省略した場合は、Trapを使用して再変更できます。
$ trap 1 2
これにより、シグナル1または2を受信した場合、実行する操作がデフォルト値にリセットされます。
コメントを残す