Reputation: 2347
I am using subprocess
to execute a python script. I can successfully run the script.
import subprocess
import time
proc = subprocess.Popen(['python', 'test.py', ''], shell=True)
proc.communicate()
time.sleep(10)
proc.terminate()
test.py
import time
while True:
print("I am inside test.py")
time.sleep(1)
I can see the message I am inside test.py
printed every second. However, I am not able to terminate the script while it is still running by proc.terminate()
.
Could someone kindly help me out?
Upvotes: 0
Views: 1252
Reputation: 2950
First things first, don't use a list to pass in the arguments for the subprocess.Popen()
if you're using the shell = True
!, change the command to string
, "python test.py"
.
Popen.communicate(input=None, timeout=None)
is a blocking class method, it shall Interact with process, and Wait for process to terminate and set the returncode attribute.
since your test.py
running infinite while loop, he will never return !
you have 2 options to timeout the process proc
that you have spawned:
communicate(timeout=5)
method. If the process proc
does not terminate after timeout
seconds, a TimeoutExpired exception
will be raised. Catching this exception and retrying communication will not lose any output (in your case you dont need the child outputs, but i will mention this in the example below). ATTENTION The child process is not killed if the timeout expires
, so in order to cleanup properly a well-behaved application should kill the child process (proc
) and finish communication.poll
method and do the timing by your calling method.communicate with timeout
try:
outs, errs = proc.communicate(timeout=15)
except TimeoutExpired:
proc.kill()
outs, errs = proc.communicate()
poll with time.sleep
proc = subprocess.Popen('python test.py', shell=True)
t=10
while proc.poll() is None and t >= 0:
print('Still sleeping')
time.sleep(1)
t -= 1
proc.kill()
Upvotes: 1
Reputation: 77407
proc.communicate
waits for the process to finish unless you include a timeout. Your process doesn't exit and you don't have a timeout so communicate
never returns. You could verify that with a print
after the call. Instead, add a timeout and catch its exception
import subprocess
import time
proc = subprocess.Popen(['python', 'test.py', ''], shell=True)
try:
proc.communicate(timeout=10)
except subprocess.TimeoutExpired:
proc.terminate()
Upvotes: 1