Goal
Launch the given command as the child process of a script, wait for it to terminate and also perform the following signal handling when a signal is sent,
When a SIGINT/SIGTERM signal is sent to the script, send it to the sub process and wait for some time to allow the sub process to exit gracefully and then send a SIGKILL if it doesn't exit.
Approach
Launched the command using
subprocess.Popen. Wait, poll usingPopen.waitandPopen.pollrespectively.Defined a custom signal handler (only for
SIGINTfor now) which takes care of sendingSIGINTto the sub process, waits for a while before polling the sub process and then sends aSIGKILLsignal to forcefully terminate the sub process.
Observation
When SIGINT (ctrl+c) is sent to the code snippet added below, the following difference in return value of Popen.poll,
- Python 2.7: Poll returns
-2(which indicates that the process was terminated by signal 2) - Python 3.7: Poll returns
None(which indicates that the process is still running)
Code
from __future__ import print_function
import time
import signal
from subprocess import Popen
from functools import partial
def handle_signal(command, signal, frame):
print("Sending signal %d to the command" % signal)
command.send_signal(signal)
# Wait for some time to allow the command to terminate gracefully
SLEEP_TIME = 3
print("Sleeping for %d seconds" % SLEEP_TIME)
time.sleep(SLEEP_TIME)
print("Return value of poll: " + str(command.poll()))
# Here send SIGKILL if poll returns None
command = Popen(["sleep", "300"])
signal.signal(signal.SIGINT, partial(handle_signal, command))
print("Launched the command, send a SIGINT")
command.wait()
Questions
Is this difference in behavior expected? If yes, then can anyone point me to the relevant documentation? (I've gone through the documentation for wait and poll in Python 2, 3 but couldn't find what might be causing this)
What is the correct way to achieve the goal described above? (ideally the code should work for both Python 2.7, 3.7 and use the
subprocessmodule)