trapコマンドはプロセスがシグナルを受信したときの動作を設定できるコマンドになります。
シグナルは、Ctrl+cによる割込みを行ったとき(SIGINT)や停止しているプロセスが再開したとき(SIGCONT)の様々な条件によってプロセスにシグナルが送られます。
プロセスが特定のシグナルを受信したときに動作する処理はシグナルごとに決められています。trapコマンドはその動作をなしにしたり、別の処理としてコマンドや関数を指定してシグナルが送られたときにその処理を行うことができます。
目次
trapコマンドの構文
trapコマンドの構文
1 |
trap [option]... [arg] [sigspec]... |
arg:コマンドや関数
sigspec:シグナル名またはシグナル番号
trapコマンドの利用例
シグナルの動作を変更
trapコマンドはコマンドまたは関数とシグナルを指定することでシグナルが発生したときの動作を変更できます。ただし、SIGKILLのシグナルについては指定しても意味がありません。
コマンド例ではCtrl+cによる割込みでのプログラムの終了の動作をechoコマンドの動作に変更しています。
test.sh
1 2 3 4 5 6 7 |
#!/bin/bash trap 'echo signal_SIGINT' SIGINT while true ; do : done |
コマンド例と実行結果
1 2 3 4 5 6 7 |
$bash test.sh ^Csignal_SIGINT ^Csignal_SIGINT ^Csignal_SIGINT ^Z [1]+ Stopped bash test.sh $ |
シグナルの指定について、始めの'SIG'という文字を省略できます。例えば、
1 |
trap 'echo signal_SIGINT' SIGINT |
は
1 |
trap 'echo signal_SIGINT' INT |
で指定できます。また、trapコマンドの-lオプション等で確認できるシグナル番号でも指定できます。例えば、SIGINTの場合は2になります。
1 |
trap 'echo signal_SIGINT' 2 |
また、第一引数に空の文字列を入れることでそのシグナルの動作は何も処理を行いません。
test2.sh
1 2 3 4 5 6 7 |
#!/bin/bash trap '' SIGINT while true ; do : done |
コマンド例と実行結果
1 2 3 4 |
$bash test2.sh ^C^C^C^Z [1]+ Stopped bash test2.sh $ |
trapコマンドの設定を確認
(-pオプション)
-pオプションを用いるとそれぞれのシグナルについて、trapコマンドの現在の設定を確認することができます。また、引数にシグナルを指定することでそのシグナルについての設定を確認することができます。
コマンド例と実行結果
1 2 3 4 5 6 7 8 |
$trap -p trap -- 'echo signal_SIGINT' SIGINT trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU $ $trap -p INT trap -- 'echo signal_SIGINT' SIGINT |
コマンド例と実行結果
1 2 3 4 5 |
$trap trap -- 'echo signal_SIGINT' SIGINT trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU |
シグナルの動作をデフォルトの動作に変更
変更されているシグナルの動作をデフォルトの動作に戻す方法はいくつかあります。
一つは第一引数に'-'を指定する方法になります。例えば、
1 |
trap - SIGINT |
のように指定します。
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$trap -p trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU $ $trap 'echo signal_SIGINT' SIGINT $trap -p SIGINT trap -- 'echo signal_SIGINT' SIGINT $ $trap - SIGINT $trap -p trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU |
他にもtrapコマンドでシグナルを一つのみを指定するとそのシグナルはデフォルトの動作になります。例えば、
1 |
trap SIGINT |
のように指定します。
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$trap -p trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU $ $trap 'echo signal_SIGINT' SIGINT $trap -p SIGINT trap -- 'echo signal_SIGINT' SIGINT $ $trap SIGINT $trap -p trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU |
また、シグナル番号のみを列挙してもデフォルトの動作にすることができます。例えば、
1 |
trap 2 15 |
のように指定します。また、2はSIGINTを、15はSIGTERMのシグナル番号になります。
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$trap -p trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU $ $trap 'echo signal' INT TERM $trap -p trap -- 'echo signal' SIGINT trap -- 'echo signal' SIGTERM trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU $ $trap 2 15 $trap -p trap -- '' SIGTSTP trap -- '' SIGTTIN trap -- '' SIGTTOU |
シグナルの一覧を表示
(-lオプション)
-lオプションを用いることで、シグナル名とシグナル番号を確認することができます。
コマンド例と実行結果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$trap -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 |
シグナルについて
それぞれのシグナルの処理としてデフォルトのアクションがそれぞれあります。
デフォルトのアクション
アクション | 意味 |
Term | プロセスの終了 |
Ign | シグナルを無視 |
Core | プロセスの終了とコアダンプファイルの作成 |
Stop | プロセスの停止 |
Cont | 停止中のプロセスを再開 |
それぞれのシグナルがどのようなときに送信されるかやデフォルトの動作はどのような処理が行われるかはそれぞれ決められています。
例えば、POSIX.1-1990 に定義されているシグナルについては以下の表のようになります。
POSIX.1-1990のシグナル表
シグナル | 番号 | アクション | 意味(シグナル送信のタイミング等) |
SIGHUP | 1 | Term | 制御端末のハングアップ(操作不能状態)の検出や 制御しているプロセスの死 |
SIGINT | 2 | Term | キーボードからの割り込み (Interrupt) |
SIGQUIT | 3 | Core | キーボードによる中止 (Quit) |
SIGILL | 4 | Core | 不正な命令 |
SIGABRT | 6 | Core | abort(3) からの中断 (Abort) シグナル |
SIGFPE | 8 | Core | 浮動小数点例外 |
SIGKILL | 9 | Term | Kill シグナル |
SIGSEGV | 11 | Core | 不正なメモリー参照 |
SIGPIPE | 13 | Term | パイプ破壊: 読み手の無いパイプへの書き出し |
SIGALRM | 14 | Term | alarm(2) からのタイマーシグナル |
SIGTERM | 15 | Term | 終了 (termination) シグナル |
SIGUSR1 | 30,10,16 | Term | ユーザー定義シグナル 1 |
SIGUSR2 | 31,12,17 | Term | ユーザー定義シグナル 2 |
SIGCHLD | 20,17,18 | Ign | 子プロセスの一時停止 (stop) または終了 |
SIGCONT | 19,18,25 | Cont | 一時停止 (stop) からの再開 |
SIGSTOP | 17,19,23 | Stop | プロセスの一時停止 (stop) |
SIGTSTP | 18,20,24 | Stop | 端末より入力された一時停止 (stop) |
SIGTTIN | 21,21,26 | Stop | バックグランドプロセスの端末入力 |
SIGTTOU | 22,22,27 | Stop | バックグランドプロセスの端末出力 |
(参考:Man page of SIGNAL)
他にも参考として、シグナルについて、manコマンドで確認する場合は、
1 |
man 7 signal |
で確認することができます。