Python 进程终止后,Popen对象的returncode为None
我正在使用Python 进程终止后,Popen对象的returncode为None,python,subprocess,Python,Subprocess,我正在使用Popen运行一个进程。我需要等待进程终止。我正在通过returncode检查进程是否已终止。当returncode与None不同时,进程必须已终止。问题是当print\u output为False时,returncode始终为None,即使进程已完成运行(终止)。但是,当print\u输出为True时,情况并非如此。我正在使用以下代码运行该流程: def run(command, print_output=True): # code mostly from: http://s
Popen
运行一个进程。我需要等待进程终止。我正在通过returncode
检查进程是否已终止。当returncode
与None
不同时,进程必须已终止。问题是当print\u output
为False
时,returncode
始终为None
,即使进程已完成运行(终止)。但是,当print\u输出为True
时,情况并非如此。我正在使用以下代码运行该流程:
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
有什么线索可以说明问题的起因吗
编辑:发现了一些很奇怪的东西。我正在运行以下代码:
run(my_command, True)
print('--------done--------')
run(my_command, False)
print('--------done--------')
'--done------'
即使执行了run(my_命令,False)
也不会被打印。我不确定它为什么不起作用,但我认为这与没有关闭流有关。以下代码起作用:
def run(command, print_output=True):
from subprocess import Popen, PIPE, STDOUT
from io import StringIO
popen = Popen(command, stdout=PIPE, stderr=STDOUT, universal_newlines=True)
out = StringIO()
for line in popen.stdout:
if print_output:
print(line, end='')
else:
out.write(line)
popen.stdout.close()
return_code = popen.wait()
if not return_code == 0:
raise RuntimeError(
'The process call "{}" returned with code {}. The return code is not 0, thus an error '
'occurred.'.format(list(command), return_code))
stdout_string = out.getvalue()
out.close()
return stdout_string
TL;博士
在subprocess.popen()之后添加popen.wait()
解释部分(类)
Python运行太快,子进程结束,但无法读取返回代码
(我真的不知道为什么会这样。欢迎解释)
我为什么要用这个:
Shell命令执行和get都返回代码和输出(stdout)
另外:请阅读.wait
上的警告有人能重现这些问题吗?我只需要在我的子流程之后添加popen.wait()
。我认为popen(…)
@Boop的评论应该是答案。或者应该是答案。很遗憾,.wait不能与管道一起使用。有其他的想法吗?
def exec_cmd(cmd):
pop = subprocess.Popen(shlex.split(cmd), stderr=subprocess.STDOUT, stdout=subprocess.PIPE)
pop.wait()
return [pop.returncode, pop.communicate()[0]]