我只是打了Ctrlc两次壳,以试图终止需要很长时间才能完成的过程。
^C
被重复两次,但过程一直在进行。
为什么Ctrlc不像往常一样退出流程?
perl -E '$SIG{TSTP} = sub { say "ha ha" }; sleep 1 while 1'
。您可能正在考虑SIGSTOP,这是一个不同的信号。
我只是打了Ctrlc两次壳,以试图终止需要很长时间才能完成的过程。
^C
被重复两次,但过程一直在进行。
为什么Ctrlc不像往常一样退出流程?
perl -E '$SIG{TSTP} = sub { say "ha ha" }; sleep 1 while 1'
。您可能正在考虑SIGSTOP,这是一个不同的信号。
Answers:
流程可以选择:
trap '' INT
在shell中使用),或者有自己的处理程序来决定不终止(或无法及时终止)。stty int '^K'
在shell中)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的第二位为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,尽管您通常不会看到这种方式。
此后Ctrl+C,将SIGINT信号发送到终端的前台进程组中的所有进程。通常是将进程放入进程组(映射到shell 作业)并告诉终端设备哪个是前台的外壳。
现在,一个过程可以:
离开其流程组。如果它移动到另一处理组(任何处理组,但一个是前景的一个),则其将不再接收在所述SIGINT Ctrl-C(还是其他键盘相关的信号如SIGTSTP,SIGQUIT)。但是,如果尝试从终端设备读取(也可能根据终端设备的设置进行写入),则它可能会被挂起(就像后台进程一样)。
举个例子:
perl -MPOSIX -e 'setpgid(0,getppid) or die "$!"; sleep 10'
不能用中断Ctrl-C。上面perl
将尝试加入ID与父进程ID相同的进程组。通常,不能保证具有该ID的进程组。但是在这里,如果该perl
命令在交互式shell的提示下单独运行,则ppid将是该shell的进程,并且该shell通常将在其自己的进程组中启动。
如果该命令还不是流程组负责人(该前台流程组的负责人),则启动一个新的流程组将具有相同的效果。
例如,根据外壳,
$ 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
在前台进程组中启动,但是在大多数shell上,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键盘顺序在理论上可以被忽略-但实际上却不是。