簡體   English   中英

使用 asyncio 將 bash 作為 Python 的子進程運行,但 bash 提示被延遲

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM