【问题标题】:How to pass subprocess control to regular stdin after using a pipe?使用管道后如何将子进程控制传递给常规标准输入?
【发布时间】:2019-04-16 22:31:33
【问题描述】:

我想做的是,在 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,因为我需要用户的输入在每次按键时生效,而不是在按下回车后才生效)?

【问题讨论】:

    标签: python subprocess pipe stdin


    【解决方案1】:

    不幸的是,在您选择写入该进程后,除了从您自己的标准输入读取并写入该进程外,没有标准方法可以在该进程期间将您自己的标准输入拼接到其他进程的标准输入首先。

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

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

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

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

    然后您将标准输入提供给该进程。但是,一旦您选择提供其标准输入的任何,您就提供其标准输入的所有,即使这意味着您必须阅读自己的标准输入。

    Linux 提供splice 系统调用(documentation at man7.orgdocumentation at linux.die.netWikipedialinux pipe data from file descriptor into a fifo),但最好的选择可能是复制数据的后台线程。

    【讨论】:

    • 那么 Python 没有任何内置方法可以将输入从标准输入转发到子进程管道?如果没有,您是否碰巧知道 Python 中有一种方法可以从用户那里获取足够低级别的输入,可以在每次按键时发送,而不仅仅是在每个换行符上发送?
    • "keypress" 通常是一个困难的概念:您可能会从根本没有连接到键盘的东西上运行。如果您确实有键盘,则有多种读取方式,具体取决于操作系统和其他项目。你希望有多便携?
    • 一点也不便携——这个特别的东西只能在树莓派上运行。有一个程序(omxplayer)通过标准输入执行键盘快捷键(例如播放/暂停的空间),我想在启动时运行一些键盘命令,然后让用户控制视频直到结束。我是否可以一遍又一遍地使用sys.stdin.read 并将其发送到管道中……?
    • (顺便说一句,omxplayer 也支持 DBUS 命令,我可能会研究一下——但如果我没有必要,我宁愿不这样做。)
    • 在这种情况下(这个东西运行 Linux),你可能想从 curses 包中借用输入读取例程:这将为你将 tty 置于一次字符模式。但是,如果您正在运行的任何程序都可以执行自己的键盘模式操作并进行命令行设置,则可能会容易得多,这样您就不必像那样中继字符。
    猜你喜欢
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-03-13
    • 2018-11-28
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多