I have a python script.py
which launches a child process and does some work in a loop. This program most of the times correctly exits when sent a SIGUSR2 and in some rare cases I don't understand it does not.
Here is the minimal working example
import os, subprocess,signal,sys,time
sub = None
shutDown = False
def handler(signum,frame):
global shutDown, sub
print("script.py: cached sig: %i " % signum)
sys.stdout.flush()
if shutDown:
print("ignoring signal: %i " % signum)
return
else:
shutDown = True
if sub is not None and not sub.poll():
print("script.py: sent signal to doStuff.sh pid: ", sub.pid)
sys.stdout.flush()
os.kill(sub.pid, signal.SIGTERM)
os.waitpid(sub.pid,0)
sys.exit(128+signum)
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGUSR2, handler)
signal.signal(signal.SIGTERM, handler)
for i in range(0,5):
print("launching %i" % i)
sub = subprocess.Popen(["./doStuff.sh"], stderr = subprocess.STDOUT)
sub.wait()
print("finished script.py")
with the doStuff
stub
function signalHandler() {
trap '' SIGINT
trap '' SIGTERM
sleep 10s
# kill ourself to signal calling process we exited on SIGINT
trap - SIGINT
kill -s SIGINT $$
}
trap_with_arg "signalHandler" SIGINT SIGTERM
trap '' SIGUSR2
echo "doStuff.sh : pid: $$"
for i in {1..100}; do
sleep 1s
done
Now launch python script.py
and send two times a SIGINT
(kill -INT -thePID
or press two times Ctrl+C
with a second in between:
launching 0
doStuff.sh : pid: 7720
^Cscript.py: cached sig: 2 /** < first time CTRL + C
script.py: sent signal to doStuff.sh pid: 7720 /** < doStuff is waiting now
^Cscript.py: cached sig: 2 /** < second time CTRL + C
ignoring signal: 2
launching 1 /** < why continuing loop??? so python
...
I am really wondering why the loop continues since there is an sys.exit
at the end of the handler and I expected that the first call to shutDownHandler
should eventually call the sys.exit
.
Does somebody see what is flawed in this program? Having a really hard time to get this to work.