一尘不染

如何使用asyncio从子进程中流式输出stdout / stderr,然后获取其退出代码?

python

在Windows上的Python 3.4下,我需要使用Python
3.4中引入的asyncio框架流式传输子进程写入stdout
/ stderr的数据,即在发生时接收其输出。之后,我还必须确定程序的退出代码。我怎样才能做到这一点?


阅读 315

收藏
2021-01-20

共1个答案

一尘不染

到目前为止,我想出的解决方案使用SubprocessProtocol来接收子进程的输出,并使用关联的传输来获取该进程的退出代码。我不知道这是否是最佳选择。我的方法基于JF
Sebastian对类似问题的回答。

import asyncio
import contextlib
import os
import locale


class SubprocessProtocol(asyncio.SubprocessProtocol):
    def pipe_data_received(self, fd, data):
        if fd == 1:
            name = 'stdout'
        elif fd == 2:
            name = 'stderr'
        text = data.decode(locale.getpreferredencoding(False))
        print('Received from {}: {}'.format(name, text.strip()))

    def process_exited(self):
        loop.stop()


if os.name == 'nt':
    # On Windows, the ProactorEventLoop is necessary to listen on pipes
    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)
else:
    loop = asyncio.get_event_loop()
with contextlib.closing(loop):
    # This will only connect to the process
    transport = loop.run_until_complete(loop.subprocess_exec(
        SubprocessProtocol, 'python', '-c', 'print(\'Hello async world!\')'))[0]
    # Wait until process has finished
    loop.run_forever()
    print('Program exited with: {}'.format(transport.get_returncode()))
2021-01-20