使用 asyncio (Python 3.4+) 异步接收长时间运行的 shell 命令的输出?

2024-01-22

我试图弄清楚如何以非阻塞方式简单地启动一些长时间运行的 shell 命令,并在它们完成时异步处理它们的输出,按照他们完成的顺序,即使这是他们开始时的另一个顺序,使用 Python 3.4 及更高版本中提供的 asyncio python 库。

我找不到执行此操作的简单示例,即使在asyncio 文档本身 https://docs.python.org/3/library/asyncio.html,这似乎也相当低级。


Use get_lines() https://stackoverflow.com/a/23616229/4279协程,异步获取 shell 命令输出并将协程传递给asyncio.as_completed() https://docs.python.org/3/library/asyncio-task.html#asyncio.as_completed,按照完成的顺序获得结果:

#!/usr/bin/env python3.5
import asyncio
import sys
from asyncio.subprocess import PIPE, STDOUT

async def get_lines(shell_command):
    p = await asyncio.create_subprocess_shell(shell_command,
            stdin=PIPE, stdout=PIPE, stderr=STDOUT)
    return (await p.communicate())[0].splitlines()

async def main():
    # get commands output concurrently
    coros = [get_lines('"{e}" -c "print({i:d}); import time; time.sleep({i:d})"'
                       .format(i=i, e=sys.executable))
             for i in reversed(range(5))]
    for f in asyncio.as_completed(coros): # print in the order they finish
        print(await f)


if sys.platform.startswith('win'):
    loop = asyncio.ProactorEventLoop() # for subprocess' pipes on Windows
    asyncio.set_event_loop(loop)
else:
    loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 asyncio (Python 3.4+) 异步接收长时间运行的 shell 命令的输出? 的相关文章

随机推荐