为什么shell会在后台进程中忽略SIGINT和SIGQUIT?

时间:2017-07-14 15:30:42

标签: linux shell unix signals posix

如果我在脚本或-c片段中处理进程,则后台进程会忽略SIGINT和SIGQUIT:

示例:

$ alias ps='ps -o pid,ppid,pgrp,sid,stat,tty,ignored,blocked,caught,wchan,min_flt,pmem,args --forest'
$ sh -c 'sleep 1000 & sleep 1000 | sleep 1000' & \
  sleep 0.01; ps |grep -v -e ps -e grep 
  PID  PPID  PGRP   SID STAT TT                IGNORED          BLOCKED           CAUGHT WCHAN   MINFL %MEM COMMAND
 6197  2143  6197  6197 Ss   pts/28   0000000000380004 0000000000010000 000000004b817efb wait    10039  0.0 -bash
 7593  6197  7593  6197 S    pts/28   0000000000000000 0000000000000000 0000000000010002 wait      148  0.0  \_ sh -c sleep 1000 & sleep 1000 | sleep 1000
 7595  7593  7593  6197 S    pts/28   0000000000000006 0000000000000000 0000000000000000 hrtime     85  0.0  |   \_ sleep 1000
 7596  7593  7593  6197 S    pts/28   0000000000000000 0000000000000000 0000000000000000 hrtime     85  0.0  |   \_ sleep 1000
 7597  7593  7593  6197 S    pts/28   0000000000000000 0000000000000000 0000000000000000 hrtime     85  0.0  |   \_ sleep 1000

这意味着如果我从交互式父shell(bash)运行kill -INT -$!(或fg后跟Ctrl-C),则-c代码段背后的睡眠过程没有到达并幸存下来。

  PID  PPID  PGRP   SID STAT TT                IGNORED          BLOCKED           CAUGHT WCHAN   MINFL %MEM COMMAND
 6197  2143  6197  6197 Ss   pts/28   0000000000380004 0000000000010000 000000004b817efb wait    10103  0.0 -bash
 7595     1  7593  6197 S    pts/28   0000000000000006 0000000000000000 0000000000000000 hrtime     85  0.0 sleep 1000

这种行为的原因是什么?可以禁用吗?

1 个答案:

答案 0 :(得分:5)

当shell在后台运行程序时,后台进程不再与原始shell绑定 - shell可以退出或被终止,后台进程应该继续运行。

如果shell是交互式的并且正在使用作业控制,它会将后台进程放在一个单独的进程组中,因此发送给shell进程组的信号不会影响它。

但是当未使用作业控制(非交互式shell中的默认作业)时,后台进程位于同一进程组中。为了避免后台进程接收刚刚用于shell的键盘信号,它显然忽略了那些子进程中的那些信号。