简体   繁体   English

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

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

What I'd like to do is to, in Python, programmatically send a few initial commands via stdin to a process, and then pass input to the user to let them control the program afterward.我想做的是,在 Python 中,以编程方式通过标准输入向进程发送一些初始命令,然后将输入传递给用户,让他们随后控制程序。 The Python program should simply wait until the subprocess exits due to user input. Python 程序应该简单地等待,直到子进程由于用户输入而退出。 In essence, what I want to do is something along the lines of:本质上,我想做的是:

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()

How can I pass stdin back to the user (not using raw_input , since I need the user's input to come into effect every keypress and not just after pressing enter)?我怎样才能将 stdin 传回给用户(不使用raw_input ,因为我需要用户的输入在每次按键时生效,而不仅仅是在按下回车键之后)?

Unfortunately, there is no standard way to splice your own stdin to some other process's stdin for the duration of that process, other than to read from your own stdin and write to that process, once you have chosen to write to that process in the first place. 不幸的是,一旦选择在第一个进程中写入该进程,除了从自己的stdin中读取并写入该进程外,没有其他方法可以在该进程的持续时间内将自己的stdin拼接到其他进程的stdin中。地点。

That is, you can do this: 也就是说,您可以执行以下操作:

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

and the process will inherit your stdin; 该过程将继承您的标准输入; or you can do this: 或者您可以这样做:

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

and then you supply the stdin to that process. 然后为该过程提供标准输入。 But once you have chosen to supply any of its stdin, you supply all of its stdin, even if that means you have to read your own stdin. 但是,一旦您选择提供其任何标准输入,就必须提供其所有标准输入,即使这意味着您必须阅读自己的标准输入。

Linux offers a splice system call ( documentation at man7.org , documentation at linux.die.net , Wikipedia , linux pipe data from file descriptor into a fifo ) but your best bet is probably a background thread to copy the data. Linux提供了一个splice系统调用( man7.org上的文档,linux.die.net上的 文档Wikipedialinux从文件描述符到fifo的管道数据 ),但是最好的选择可能是后台线程来复制数据。

So searching for this same thing, at least in my case, the pexpect library takes care of this:所以搜索同样的东西,至少在我的例子中,pexpect 库会处理这个:

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

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

As by its name you can automate a lot of interaction before handing it over to the user.顾名思义,您可以在将其移交给用户之前自动执行大量交互。

Note, in your case you may want an output filter: Using expect() and interact() simultaneously in pexpect请注意,在您的情况下,您可能需要一个 output 过滤器: Using expect() and interact() simultaneously in pexpect

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM