首页 > 解决方案 > 在实时读取stdout和stderr的同时与子进程交互

问题描述

我需要围绕一个shell命令编写一个包装器,该命令将其stdout和stderr分别实时打印回stdout和stderr,同时如果进程提示输入,还允许用户交互并将stdin发送给它。

请注意,这pexpect.interact()几乎解决了问题,只是它将所有 stdout 和 stderr 组合在一起并将其发送回 stdout。而且似乎没有办法阻止它这样做。

到目前为止,我所拥有的是一种通过以下方式从进程中读取 stdout 和 stderr 的方法subprocess.Popen

def _popen_command(
    command: List[str]
) -> None:
    """
    Run a shell command with Popen line by line
    in real time without redirecting stdout or stderr.
    """

    with subprocess.Popen(
        command,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE
    ) as proc:

        selector = selectors.DefaultSelector()
        selector.register(proc.stdout, selectors.EVENT_READ)  
        selector.register(proc.stderr, selectors.EVENT_READ)  

        eof = False
        while not eof:
            for key, _ in selector.select():
                data = key.fileobj.read1(1).decode()  

                if not data:
                    eof = True

                if key.fileobj is proc.stdout:
                    print(data, end="")
                else:
                    print(data, end="", file=sys.stderr)

我不相信 Stack Overflow 中存在所有这些特性的答案:实时、逐行处理 stdout、stderr,并将它们分别打印回 stdout、stderr,并且还允许与 stdin 进行任意交互。

是否有可能做到这一点?

标签: python

解决方案


推荐阅读