I'm running a process with the use of Popen
. I need to wait for the process to terminate. I'm checking that the process have terminated through the returncode
. When returncode
is different from None
the process must have terminated. The problem is that when print_output
is False
the returncode
is always None
, even when the process have finished running (terminated). This is however not the case when print_output
is True
. I'm using the following code to run the process:
def run(command, print_output=True):
# code mostly from: http://sharats.me/the-ever-useful-and-neat-subprocess-module.html
from subprocess import Popen, PIPE
from threading import Thread
from queue import Queue, Empty
from time import sleep
io_q = Queue()
def stream_watcher(identifier, stream):
for line in stream:
io_q.put((identifier, line))
if not stream.closed:
stream.close()
with Popen(command, stdout=PIPE, stderr=PIPE, universal_newlines=True) as proc:
if print_output:
Thread(target=stream_watcher, name='stdout-watcher', args=('STDOUT', proc.stdout)).start()
Thread(target=stream_watcher, name='stderr-watcher', args=('STDERR', proc.stderr)).start()
def printer():
while True:
try:
# Block for 1 second.
item = io_q.get(True, 1)
except Empty:
# No output in either streams for a second. Are we done?
if proc.poll() is not None:
break
else:
identifier, line = item
print(identifier + ':', line, end='')
Thread(target=printer, name='printer').start()
while proc.returncode is None:
sleep(2)
proc.poll()
if not proc.returncode == 0:
raise RuntimeError(
'The process call "{}" returned with code {}. The return code is not 0, thus an error '
'occurred.'.format(list(command), proc.returncode))
return proc.stdout, proc.stderr
Any clues to what might cause this problem?
EDIT: Discovered something pretty weird. I'm running the following code:
run(my_command, True)
print('--------done--------')
run(my_command, False)
print('--------done--------')
'--------done--------'
is never printed even though run(my_command, False)
gets executed.
Popen has a built-in method to determine if the subprocess is still running, Popen. poll(). In your code process.
The returncode() function provides a simple way to get the return code set by the command executed. The command is run in a sub-process and must require no input. For example, suppose you needed to get the return code set by the following python script: import sys sys. exit(4)
Python method popen() opens a pipe to or from command. The return value is an open file object connected to the pipe, which can be read or written depending on whether mode is 'r' (default) or 'w'. The bufsize argument has the same meaning as in open() function.
Popen Function The function should return a pointer to a stream that may be used to read from or write to the pipe while also creating a pipe between the calling application and the executed command. Immediately after starting, the Popen function returns data, and it does not wait for the subprocess to finish.
add popen.wait()
after subprocess.Popen()
Python goes too fast and the child process is ended but returncode can't be read
(I don't really know why it does that. Explanations welcome)
Shell command execution and get both return code and output (stdout)
def exec_cmd(cmd):
pop = subprocess.Popen(shlex.split(cmd), stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
pop.wait()
return [pop.returncode, pop.communicate()[0]]
Also: please read the .wait
warning on the popen page
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With