使用管道后如何将子进程控制传递给常规标准输入?

How to pass subprocess control to regular stdin after using a pipe?

我想做的是,在 Python 中,以编程方式通过标准输入向进程发送一些初始命令,然后将输入传递给用户,让他们随后控制程序。 Python 程序应该简单地等待,直到子进程由于用户输入而退出。本质上,我想做的是:

import subprocess

p = subprocess.Popen(['cat'], stdin=subprocess.PIPE)

# Send initial commands.
p.stdin.write(b"three\ninitial\ncommands\n")
p.stdin.flush()

# Give over control to the user.
# …Although stdin can't simply be reassigned
# in post like this, it seems.
p.stdin = sys.stdin

# Wait for the subprocess to finish.
p.wait()

我如何将标准输入传回给用户(不使用raw_input,因为我需要用户的输入在每次按键时生效,而不是在按下后才生效输入)?

不幸的是,除了从您自己的标准输入中读取并写入该进程之外,没有标准的方法可以在该过程的持续时间内将您自己的标准输入拼接到该进程的标准输入,一旦您选择写入首先是这个过程。

也就是说,你可以这样做:

proc = subprocess.Popen(...)  # no stdin=

并且该进程将继承您的标准输入;或者你可以这样做:

proc = subprocess.Popen(..., stdin=subprocess.PIPE, ...)

然后您向该进程提供标准输入。但是,一旦您选择提供其标准输入的 any,您就提供其标准输入的 all,即使这意味着您必须阅读自己的标准输入.

Linux 提供了一个 splice 系统调用 (documentation at man7.org, documentation at linux.die.net, Wikipedia, ) 但你最好的选择可能是复制数据的后台线程。

所以搜索同样的东西,至少在我的情况下,pexpect 库会处理这个:

https://pexpect.readthedocs.io/en/stable/

p = pexpect.spawn("ssh myhost")
p.sendline("some_line")
p.interact()

顾名思义,您可以在将其移交给用户之前自动执行大量交互。

请注意,在您的情况下,您可能需要一个输出过滤器: