使用asyncio将bash作为Python的子进程运行,但bash提示会延迟
我希望从Python的asyncio控制一个长时间运行的交互式Bash子进程,一次发送一个命令,然后从中接收结果 下面的代码片段在Python 3.7.0达尔文内核版本16.7.0中运行得非常好,除了Bash提示不会立即出现在使用asyncio将bash作为Python的子进程运行,但bash提示会延迟,python,bash,subprocess,python-asyncio,Python,Bash,Subprocess,Python Asyncio,我希望从Python的asyncio控制一个长时间运行的交互式Bash子进程,一次发送一个命令,然后从中接收结果 下面的代码片段在Python 3.7.0达尔文内核版本16.7.0中运行得非常好,除了Bash提示不会立即出现在stderr上,而是在其他东西写入stderr之前显示为“排队” 这是一个问题,因为原始程序需要接收Bash提示符才能知道上一个命令已经完成 from asyncio.subprocess import PIPE import asyncio async def run
stderr
上,而是在其他东西写入stderr
之前显示为“排队”
这是一个问题,因为原始程序需要接收Bash提示符才能知道上一个命令已经完成
from asyncio.subprocess import PIPE
import asyncio
async def run():
proc = await asyncio.create_subprocess_exec(
'/bin/bash', '-i', stdin=PIPE, stdout=PIPE, stderr=PIPE
)
async def read(stream):
message = 'E' if stream is proc.stderr else 'O'
while True:
line = await stream.readline()
if line:
print(message, line)
else:
break
async def write():
for command in (b'echo PS1=$PS1', b'ls sub.py', b'ls DOESNT-EXIST'):
proc.stdin.write(command + b'\n')
await proc.stdin.drain()
await asyncio.sleep(0.01) # TODO: need instead to wait for prompt
await asyncio.gather(
read(proc.stderr),
read(proc.stdout),
write(),
)
asyncio.run(run())
结果:
E b'bash: no job control in this shell\n'
O b'PS1=\\u@\\h:\\w$\n'
O b'sub.py\n'
E b'tom@bantam:/code/test/python$ tom@bantam:/code/test/python$ tom@bantam:/code/test/python$ ls: DOESNT-EXIST: No such file or directory\n'
请注意,这三个提示在最后一起出现,并且只有一次是故意导致错误的。当然,期望的行为是提示在出现时立即出现
使用proc.stderr.read()
看到bash:no job control in this shell
消息出现在stderr
中,我有点惊讶,因为我正在运行bash-I
,而且$PS1
已设置,我不知道这是否与问题有关,但还无法进一步解决。这让我耽搁了半天,但当我写完问题后,我花了十分钟想出了解决办法
如果我修改提示符,使其以\n
结尾,那么proc.stderr
实际上是刷新的,并且一切工作都绝对完美