たった今 Ctrlc 終了するまでに時間がかかるプロセスを停止するために、私のシェルで2回。
^C
は2回エコーされましたが、プロセスは続行されました。
なぜしなかった Ctrlc 通常のようにプロセスを終了しますか?
プロセスは以下を選択できます。
trap '' INT
の場合と同様)または終了しないことを決定する(またはタイムリーに終了できない)独自のハンドラーがある.stty int '^K'
など)。stty -isig
など)。または、システムコールの途中で中断できない場合など、中断できない場合もあります。
Linux(比較的最近のカーネルを使用)では、プロセスが無視しているかどうか、およびhandling SIGINTの出力を確認することで、
$ kill -l INT
2
$ grep Sig "/proc/$pid/status"
SigQ: 0/63858
SigPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000002
SigCgt: 0000000000000000
SIGINTは2です。上記のSigIgnの2番目のビットは1です。これは、SIGINTが無視されることを意味します。
あなたはそれを自動化することができます:
$ SIG=$(kill -l INT) Perl -lane 'print $1 if $F[0] =~ /^Sig(...):/ &&
$F[1] & (1<<($ENV{SIG}-1))' < "/proc/$pid/status"
Ign
現在のintr
文字が何であるか、または特定の端末でisig
が有効になっているかどうかを確認するには:
$ stty -a < /dev/pts/0
[...] intr = ^C [...] isig
(intr
文字の上は^C
です(通常、押すと端末(エミュレーター)によって送信される文字) CTRL-C および入力信号は無効になりません。
$ stty -a < /dev/pts/1
[...] intr = ^K [...] -isig
(intr
文字は^K
であり、isig
は/dev/pts/1
に対して無効です)。
完全を期すために、プロセスがSIGINTの受信を停止するために他に2つの方法がある場合がありますが、これは通常見られるものではありません。
に Ctrl+C、SIGINTシグナルは端末のフォアグラウンドプロセスグループのすべてのプロセスに送信されます。通常は、シェルがプロセスグループにプロセスを配置し(シェルjobsにマップされます)、端末デバイスにフォアグラウンドであると伝えます。
これでプロセスは次のことができます:
そのプロセスグループを離れます。別のプロセスグループ(フォアグラウンド 1であるプロセスグループ以外のプロセスグループ)に移動すると、SIGINTを受け取りません。 Ctrl-C (SIGTSTP、SIGQUITのような他のキーボード関連の信号も)。ただし、(バックグラウンドプロセスのように)端末デバイスから読み取り(端末デバイスの設定によっては書き込みも可能)しようとした場合は、中断される可能性があります。
例として:
Perl -MPOSIX -e 'setpgid(0,getppid) or die "$!"; sleep 10'
と中断することができませんでした Ctrl-C。上記のPerl
は、親プロセスIDと同じIDを持つプロセスグループに参加しようとします。一般に、そのIDを持つそのようなプロセスグループが存在するという保証はありません。ただし、ここでは、対話型シェルのプロンプトでPerl
コマンドが単独で実行される場合、ppidがシェルのプロセスになり、シェルは通常、独自のプロセスグループで起動されます。
コマンドがまだプロセスグループリーダー(そのフォアグラウンドプロセスグループのリーダー)でない場合は、新しいプロセスグループを開始しても同じ効果があります。
たとえば、シェルによっては、
$ ps -j >&2 | Perl -MPOSIX -e 'setpgid(0,0) or die "$!"; sleep 10'
PID PGID SID TTY TIME CMD
21435 21435 21435 pts/12 00:00:00 zsh
21441 21441 21435 pts/12 00:00:00 ps
21442 21441 21435 pts/12 00:00:00 Perl
同じ効果があります。 ps
とPerl
はフォアグラウンドプロセスグループで開始されますが、ほとんどのシェルでは、ps
がそのグループのリーダーになります(ps
上記の出力では、ps
とPerl
の両方のpgidがps
のpidであるため、Perl
は独自のプロセスグループを開始できます。
または、フォアグラウンドプロセスグループを変更することもできます。基本的に、ttyデバイスにSIGINTを他のプロセスグループに送信するように指示します。 Ctrl+C
Perl -MPOSIX -e 'tcsetpgrp(0、getppid)またはdie $ !;寝る5 '
そこで、Perl
は同じプロセスグループに残りますが、代わりに、フォアグラウンドプロセスグループは、その親プロセスIDと同じIDのグループであることを端末デバイスに伝えています(上記の注を参照)。