[英]Running bash as a subprocess to Python using asyncio, but bash prompts are delayed
我希望從 Python 的 asyncio 控制一個長時間運行的交互式 Bash 子進程,一次發送一個命令,然后從它接收結果。
The code fragment below works perfectly well in Python 3.7.0, Darwin Kernel Version 16.7.0, except that Bash prompts do not appear immediately on stderr
, but appear to "queue up" until something else writes to 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()
而不是proc.stderr.read()
會產生更多代碼,但結果相同。
看到bash: no job control in this shell
消息出現在stderr
中,我有點驚訝,因為我正在運行bash -i
,但我想知道是否有這個問題,因為$PS1
PS19CCE69Z無法更進一步。
這讓我呆了半天,但是當我寫完問題后,我花了十分鍾才想出一個解決方法。
如果我修改提示使其以\n
結尾,那么proc.stderr
實際上已被刷新,並且一切都運行得非常完美。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.