Ctrlc終了に時間がかかるプロセスを停止するために、シェルを2回たたくだけです。
^C
2回エコーされましたが、プロセスは続行されました。
Ctrlc通常のようにプロセスを終了しなかったのはなぜですか?
perl -E '$SIG{TSTP} = sub { say "ha ha" }; sleep 1 while 1'
。おそらく別のシグナルであるSIGSTOPを考えているでしょう。
Ctrlc終了に時間がかかるプロセスを停止するために、シェルを2回たたくだけです。
^C
2回エコーされましたが、プロセスは続行されました。
Ctrlc通常のようにプロセスを終了しなかったのはなぜですか?
perl -E '$SIG{TSTP} = sub { say "ha ha" }; sleep 1 while 1'
。おそらく別のシグナルであるSIGSTOPを考えているでしょう。
回答:
プロセスは以下を選択できます。
trap '' INT
シェル内など)、終了しないことを決定する(または適時に終了しない)独自のハンドラーを用意します。stty int '^K'
シェル内のような)他のものであることを端末デバイスに伝えますstty -isig
シェルの場合のように)シグナルを送信しないように端末デバイスに指示します。または、中断できないシステムコールの途中など、中断できない場合もあります。
Linux(比較的最近のカーネルを使用)では、プロセスが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シグナルが端末のフォアグラウンドプロセスグループのすべてのプロセスに送信されます。通常、プロセスグループ(シェルジョブにマップされます)にプロセスを配置し、フォアグラウンドデバイスをターミナルデバイスに通知するのはシェルです。
これでプロセスは次のことができます:
そのプロセスグループを離れます。別のプロセスグループ(フォアグラウンドプロセスグループ以外のプロセスグループ)に移動すると、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
、両方のPGID上記の出力ps
とperl
のPIDであるps
)ので、perl
独自のプロセスグループを開始することができます。
または、フォアグラウンドプロセスグループを変更することもできます。基本的に、ttyデバイスにSIGINTを他のプロセスグループに送信するように指示します。Ctrl+C
perl -MPOSIX -e 'tcsetpgrp(0、getppid)またはdie $ !; 5フィート寝る
そこでperl
は、同じプロセスグループに留まりますが、代わりに、フォアグラウンドプロセスグループは、親プロセスIDと同じIDのグループであることを端末デバイスに伝えています(上記の注を参照)。
hdparm
、smartctl
永久にハングし、CTRL + Cでそれらを強制終了することはできません。/ のstat列ps aux
またはtop
/ のS列を見ると、プロセスが割り込み不可能なスリープ状態にあるかどうかがわかりますhtop
- D
割り込み不可能なスリープを意味します。これは必ずしも悪いことではありませんが、プロセスが大量のIOを実行していることを意味している可能性があります。
kill -9 %
することです。信号9は無視できません。また、中断信号も無視できません。CTRL + Zキーボードシーケンスは理論的には無視できますが、実際にはありません。