问题
If I background a processes in a script or a -c snippet, the backgrounded processes ignores SIGINT and SIGQUIT:
Example:
$ 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
This means that if I run kill -INT -$!
(or fg
followed by Ctrl-C
) from the interactive parent shell (bash), the sleep processes backgrounded from the -c
snippet isn't reached and survives.
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
What is the reason for this behavior? Can it be disabled?
回答1:
When a shell runs a program in the background, the background process is not supposed to be tied to the original shell any more -- the shell can exit or be killed, and the background process should continue running.
If the shell is interactive and job control is being used, it puts the background process in a separate process group, so signals sent to the shell process group don't affect it.
But when job control is not being used, which is the default in non-interactive shells, the background process is in the same process group. To avoid the background process receiving keyboard signals that are just intended for the shell, it apparently ignores those signals in those child processes.
来源:https://stackoverflow.com/questions/45106725/why-do-shells-ignore-sigint-and-sigquit-in-backgrounded-processes