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?
In general, yes, execution continues after the handler returns.
The SIGKILL signal is used to cause immediate program termination. It cannot be handled or ignored, and is therefore always fatal. It is also not possible to block this signal.
SIGTERM is the preferred way as the process has the chance to terminate gracefully. As a process can override the default action for SIGINT, SIGTERM, and SIGQUIT, it can be the case that neither of them finishes the process.
The SIGSTOP signal instructs the operating system to stop a process for later resumption. You might also like to now that SIGINT is a signal that is issued when you press CTRL+C at the terminal.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With