如果我在脚本或-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
这意味着如果我运行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
这种行为的原因是什么? 它可以被禁用?
当一个shell在后台运行程序时,后台进程不应该被绑定到原来的shell – shell可以退出或者被终止,后台进程应该继续运行。
如果shell是交互式的,并且正在使用作业控制,则它将后台进程放在一个单独的进程组中,因此发送到shell进程组的信号不会影响它。
但是,当没有使用作业控制时,这是非交互式shell中的默认设置,后台进程位于同一个进程组中。 为了避免后台进程接收到仅用于shell的键盘信号,显然忽略了这些子进程中的那些信号。