Bash – SIGINT not being propagated to background child process

background-processbashkillprocesssignals

I need to send SIGINT to terminate a process gracefully but I can't.

This is a sample, because the environment in which the execution occurs is 'unknown' (a bash script in travis.com)

I managed to get (simulate) the same behaviour, by launching a process like this (command &) &

vagrant@host:~$ (sleep 40 &) &
[1] 8473
vagrant@host:~$ ps -o pid,pgid,args
  PID  PGID COMMAND                     
 2787  2787 -bash                       
 8474  8473 sleep 40                    
 8490  8490 ps -o pid,pgid,args  
[1]+  Done                    ( sleep 40 & )
vagrant@host:~$ kill -INT 8474  ##### here I send SIGINT to the process
vagrant@host:~$ kill -INT -8473 ##### here I send SIGINT to the process group
vagrant@host:~$ ps -o pid,pgid,args
  PID  PGID COMMAND                     
 2787  2787 -bash                       
 8474  8473 sleep 40                    
 8559  8559 ps -o pid,pgid,args  

I googled and read a lot about signals and groups and I can't understand what is happening here. Is the signal being ignored at some point? What is happening? How can I send SIGINT to that sleep process?

EDIT: if SIGTERM is used, the process is killed (maybe the parent subshell is killed?)

Best Answer

In order to have a non-interactive job respond to SIGINT, you need to create a handler for SIGINT:

$ ( (trap "echo Got SigInt" SIGINT; sleep 60) & ) &
[1] 13619
$ 
[1]+  Done                    ( ( trap "echo Got SigInt" SIGINT; sleep 60 ) & )
$ ps -o pid,pgid,args
  PID  PGID COMMAND
11972 11972 bash
13620 13619 bash
13621 13619 sleep 60
13622 13622 ps -o pid,pgid,args
$ kill -INT 13620
$ kill -INT 13621
$ Got SigInt

Sending SIGINT to the sleep process

As Stéphane Chazelas suggests in the comments, if the goal is to return to the default behavior of SIGINT, we can just use trap - SIGINT. For example:

$ ( (trap - SIGINT; sleep 60) & ) &
[1] 16690
$ ps -o pid,pgid,args
  PID  PGID COMMAND
11972 11972 bash
16691 16690 bash
16692 16690 sleep 60
16693 16693 ps -o pid,pgid,args
[1]+  Done                    ( ( trap - SIGINT; sleep 60 ) & )
$ kill -INT 16692
$ ps -o pid,pgid,args
  PID  PGID COMMAND
11972 11972 bash
16698 16698 ps -o pid,pgid,args