Reputation: 643
I have a python code as following:
import threading
import time
import subprocess, os, sys, psutil, signal
from signal import SIGKILL
def processing():
global p_2
global subp_2
.
.
.
if condition1: #loop again
threading.Timer(10,processing).start()
if condition2:
signal.signal(signal.SIGINT, signal_handler)
#signal.signal(signal.SIGTERM, signal_handler)
subp_2.terminate()
#os.kill(subp_2.pid, 0)
#subp_2.kill()
print " Status p_2: ", p_2.status
def signal_handler(signal, frame):
print('Exiting')
sys.exit(0)
def function():
global p_1
global subp_1
.
.
.
if condition1: #loop again
threading.Timer(5,function).start()
if condition2:
signal.signal(signal.SIGINT, signal_handler)
#signal.signal(signal.SIGTERM, signal_handler)
subp_1.terminate()
#os.kill(subp_1.pid, 0)
#subp_1.kill()
print " Status p_1: ", p_1.status
threading.Timer(10,processing).start()
subp_2 = subprocess.Popen('./myScript2.sh %s %s' % (arg0, arg1), shell=True)
p_2 = psutil.Process(subp_2.pid)
if __name__ == '__main__':
global p_1
global subp_1
.
.
.
subp_1 = subprocess.Popen(["/.../myScript1.sh"], shell=True)
p_1 = psutil.Process(subp_1.pid)
threading.Timer(5,function).start()
I could not kill the processe subp_1 and subp_2. Whatever I tried: .terminate(), .kill() or os.kill() I am still getting process status running. Could anyone tell me please what am I missing ? Any hint is appreciated.
Upvotes: 2
Views: 3891
Reputation: 879411
When you use shell=True
, first a subprocess is spawned which runs the shell. Then the shell spawns a subprocess which runs myScript2.sh
. The subprocess running the shell can be terminated without terminating the myScript2.sh
subprocess.
If you can avoid using shell=True
, then that would be one way to avoid this problem. If using user input to form the command, shell=True
should definitely be avoided, since it is a security risk.
On Unix, by default, the subprocess spawned by subprocess.Popen
is not a session leader. When you send a signal to a session leader, it is propagated to all processes with the same session id. So to have the shell pass the SIGTERM
to myScript2.sh
, make the shell a session leader.
For Python versions < 3.2 on Unix, that can be done by having the shell process run os.setsid()
:
import os
subp_2 = subprocess.Popen('./myScript2.sh %s %s' % (arg0, arg1),
shell=True,
preexec_fn=os.setsid)
# To send SIGTERM to the process group:
os.killpg(subp_2.pid, signal.SIGTERM)
For Python versions >= 3.2 on Unix, pass start_new_session=True
to Popen
.
For Windows, see J.F. Sebastian's solution.
Upvotes: 4