从子进程输出中读取python

问题描述 投票:0回答:3

我正在使用“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() ,但因为子进程需要时间,而且我无论如何都需要等待其完成。

python popen
3个回答
2
投票

这应该有效:

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)

0
投票

使用

subprocess.check_output
。它返回命令的输出。


0
投票

实际上,当我想使用

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()
© www.soinside.com 2019 - 2024. All rights reserved.