Sending SIGINT to process groups sometimes gets ignored
7
votes
2
answers
2424
views
I start a process group from bash. Then I send SIGINT to the entire process
group. Sometimes the SIGINT kills the processes, sometimes does not. Why does
SIGINT sometimes gets ignored ?
I see different behavior depending on whether the process group is started in
the background or not, on nestedness of bash shells and on Mac/Linux operating
system. I would really appreciate if someone can shed some light on this.
In the following examples I use this python executable called
sleep_in_pgrp.py
#!/usr/bin/env python2.7
import os;
import subprocess
os.setpgrp();
subprocess.check_call(["sleep","10000"]);
It creates a process group and starts sleep. The observed phenomena should not
be related to python. I use python only because bash does not have a setpgrp
command or builtin. **Update**: Apparently one could also run an interactive
shell to create a [new process group](https://unix.stackexchange.com/a/18711/212862)
**1) Start the process group in the background and wait on the leader. SIGINT gets ignored.**
Execute the following command:
$ bash -c ' { sleep_in_pgrp.py; } & wait $! '
Bash starts python in the background and waits on it.
In another terminal:
$ ps -Heo pid,ppid,tpgid,pgid,sid,user,args
PID PPID TPGID PGID SID COMMAND
2507 1574 2963 2507 2507 -bash
2963 2507 2963 2963 2507 bash -c { sleep_in_pgrp.py; } & wait $!
2964 2963 2963 2963 2507 bash -c { sleep_in_pgrp.py; } & wait $!
2965 2964 2963 2965 2507 python2.7 ./sleep_in_pgrp.py
2966 2965 2963 2965 2507 sleep 10000
SIGINT’ing the proccess group of python **does not kill any processes**. What can be the reason ?
$ sudo kill -s SIGINT -- -2965
**2) Start the process group in the foreground. SIGINT works.**
If I remove the & wait $!
, SIGINT kills the process group as expected. I do not know why but I am not surprised SIGINT killed the processes in this case.
$ bash -c ' { sleep_in_pgrp.py; } '
In another terminal:
$ ps -Heo pid,ppid,tpgid,pgid,sid,user,args
PID PPID TPGID PGID SID COMMAND
2507 1574 3352 2507 2507 -bash
3352 2507 3352 3352 2507 bash -c { sleep_in_pgrp.py; }
3353 3352 3352 3353 2507 python2.7 ./sleep_in_pgrp.py
3354 3353 3352 3353 2507 sleep 10000
SIGINT kills the process group.
$ sudo kill -s SIGINT -- -3353
**3) Removing the subshell while running python in the background. SIGINT works.**
I was very surprised that the shell nestedness affects the behavior here. I cannot think of any explanation why.
I remove the bash -c
at the start:
$ { sleep_in_pgrp.py; } & wait $!
In another terminal:
$ ps -Heo pid,ppid,tpgid,pgid,sid,user,args
PID PPID TPGID PGID SID COMMAND
2507 1574 2507 2507 2507 -bash
3488 2507 2507 3488 2507 -bash
3489 3488 2507 3489 2507 python2.7 ./sleep_in_pgrp.py
3490 3489 2507 3489 2507 sleep 10000
SIGINT kills the process group.
$ sudo kill -s SIGINT -- -2507
**4) Running the first command in Mac: SIGINT works.**
The first 2 commands ran in a CentOs7 VM.
$ uname -a
Linux ip-10-229-193-124 3.10.0-693.5.2.el7.x86_64 #1 SMP Fri Oct 13 10:46:25 EDT 2017 x86_64 x86_64 x86_64 GNU/Linux
I now execute the first command with backgrounded python in a subshell in mac.
$ uname -a
Darwin mbp-005063 15.6.0 Darwin Kernel Version 15.6.0: Sun Jun 4 21:43:07 PDT 2017; root:xnu-3248.70.3~1/RELEASE_X86_64 x86_64
In Mac:
$ bash -c ' { sleep_in_pgrp.py; } & wait $! '
In another terminal:
$ PID PPID TPGID PGID SESS COMMAND
18741 40096 18741 18741 0 bash -c { sleep_in_pgrp.py; } & wait $!
18742 18741 18741 18741 0 bash -c { sleep_in_pgrp.py; } & wait $!
18743 18742 18741 18743 0 /usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python ./sleep_in_pgrp.py
18744 18743 18741 18743 0 sleep 10000
40094 2423 18741 40094 0 /Applications/iTerm.app/Contents/MacOS/iTerm2 --server /usr/bin/login -fpl hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
40095 40094 18741 40095 0 /usr/bin/login -fpl hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
40096 40095 18741 40096 0 -bash
-+= 00001 root /sbin/launchd
\-+= 02423 hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2
\-+= 40094 hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2 --server /usr/bin/login -fpl hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
\-+= 40095 root /usr/bin/login -fpl hbaba /Applications/iTerm.app/Contents/MacOS/iTerm2 --launch_shell
\-+= 40096 hbaba -bash
\-+= 18741 hbaba bash -c { sleep_in_pgrp.py; } & wait $!
\-+- 18742 hbaba bash -c { sleep_in_pgrp.py; } & wait $!
\-+= 18743 hbaba /usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python ./sleep_in_pgrp.py
\--- 18744 hbaba sleep 10000
And in this case, SIGINT also kills the process group
$ sudo kill -s INT -18743
Bash version in CentOs7 is
$ echo $BASH_VERSION
4.2.46(2)-release
In Mac the bash version is
$ echo $BASH_VERSION
4.4.12(1)-release
----------------------------
This [answer](https://unix.stackexchange.com/a/149756/212862) explains how
Ctrl+C sends SIGINT to the process group. That is what I am trying to do here
sending SIGINT to a process group.
This [answer](https://unix.stackexchange.com/a/256318/212862) mentions that non
interactive jobs require a SIGINT handler. I am not sure it explains the
varying behavior I see. I am also wondering whether waiting on a background
process affects the SIGINT handling by that process.
Asked by Hakan Baba
(919 rep)
Oct 29, 2017, 08:03 AM
Last activity: Jan 21, 2025, 06:00 AM
Last activity: Jan 21, 2025, 06:00 AM