我正在使用“Popen”运行子进程。我需要阻塞直到这个子进程完成,然后读取它的输出。
p = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE, encoding="utf-8")
p.communicate():
output = p.stdout.readline()
print(output)
我收到一个错误
ValueError: I/O operation on closed file.
子进程完成后如何读取输出,我不想使用 poll() ,但因为子进程需要时间,而且我无论如何都需要等待其完成。
这应该有效:
p = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE, encoding="utf-8")
output, error = p.communicate()
print(output)
if error:
print('error:', error, file=sys.stderr)
subprocess.run()
:
p = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("output:", p.stdout)
if proc.stderr:
print("error:", p.stderr, file=sys.stderr)
subprocess.check_output
。它返回命令的输出。
实际上,当我想使用
python3 -c "import time;time.sleep(3);print(1)"
或 subprocess.run
运行 subprocess.Popen
时,我面临着在子进程结束之前不收集输出并返回的问题。
唯一可行的解决方案对我来说是/是下面的asyncio
代码(针对3.6),但对于较新的版本将非常相似:
class ShellCommand(Command):
OK = 0
ENCODING = 'utf-8'
def run(self, args: List[str]) -> str:
cmd = ' '.join(args)
logging.info('executing %s', cmd)
async def _run(cmd: str, future: asyncio.Future):
proc = await asyncio.create_subprocess_shell(
cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.STDOUT)
stdout, stderr = await proc.communicate()
if proc.returncode != type(self).OK:
raise ValueError(f'Return code: {proc.returncode}', f'Message: {stderr.decode(type(self).ENCODING)}')
future.set_result(stdout.decode(type(self).ENCODING))
asyncio.set_event_loop(asyncio.new_event_loop())
loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(_run(cmd, future), loop=loop)
loop.run_until_complete(future)
loop.close()
return future.result()