Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do shells ignore SIGINT and SIGQUIT in backgrounded processes?

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?

like image 745
PSkocik Avatar asked Jul 14 '17 15:07

PSkocik


People also ask

Could a program continue running after receiving SIGINT?

In general, yes, execution continues after the handler returns.

Can a process ignore SIGKILL?

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.

Should I use SIGINT or Sigterm?

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.

What is the difference between SIGINT and Sigstop?

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.


1 Answers

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.

like image 91
Barmar Avatar answered Nov 15 '22 23:11

Barmar