这是我从子进程异步读取stdin / stdout并从Python打印它的最佳尝试:
import asyncio
import subprocess
from asyncio.subprocess import STDOUT, PIPE, DEVNULL
async def start_stream():
return await asyncio.create_subprocess_shell(
'watch ls /proc',
stdout=PIPE,
stderr=PIPE,
limit=1024
)
async def spawn():
ev_proc = await start_stream()
while True:
stdout, stderr = await ev_proc.communicate()
print(stdout, stderr)
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(spawn())
为什么打印功能没有输出任何东西?
答案 0 :(得分:1)
您的watch
进程永不终止,communicate()
等待进程终止,因此stdout
永远不会到达您的脚本。
https://docs.python.org/3/library/asyncio-subprocess.html
协程通信协议(输入=无)与流程交互:将数据发送到 标准输入。从stdout和stderr读取数据,直到达到文件结尾。 等待进程终止。
尝试以下受https://stackoverflow.com/a/24435988/2776376启发的代码。
它使用pipe_data_received
,然后len > 16
只是为了防止打印空行。
SubprocessProtocol.pipe_data_received(fd,data)
子进程将数据写入其stdout或stderr管道时调用。 fd是管道的整数文件描述符。 data是包含数据的非空字节对象。
import asyncio
class SubprocessProtocol(asyncio.SubprocessProtocol):
def pipe_data_received(self, fd, data):
if fd == 1:
text = data.decode()
if len(text.strip()) > 16:
print(text.strip())
def process_exited(self):
loop.stop()
loop = asyncio.get_event_loop()
ls = loop.run_until_complete(loop.subprocess_exec(
SubprocessProtocol, 'watch', 'ls', '/proc'))
loop.run_forever()