【问题标题】:subprocess.Popen - redirect stdin againsubprocess.Popen - 再次重定向标准输入
【发布时间】:2016-10-13 08:23:08
【问题描述】:

假设有一个名为“ABC”的程序,它从标准输入读取 4 个整数并对其进行处理。

最近,我认为我们可以使用管道将输入提供给 ABC,如下所示:

# send.py
import subprocess

p = subprocess.Popen(['ABC'], stdin = subprocess.PIPE)
print >>p.stdin, '1 2 3 4'

我的问题是:我们可以在调用subprocess.Popen 后再次重定向标准输入吗?例如,

# send.py
import subprocess

p = subprocess.Popen(['ABC'], stdin = subprocess.PIPE)
print >>p.stdin, '1 2 3'

(Redirect p.stdin to terminal's stdin)

,这样我们就可以在终端输入第四个整数到ABC了。

【问题讨论】:

  • 您希望send.py 从标准输入读取然后写入ABC 的标准输入?是的,你绝对可以做到。在这种情况下,它不被称为“重定向”——每个程序都有自己的标准输入。使用input()sys.stdin.read()

标签: python python-2.7 subprocess popen


【解决方案1】:

重定向发生在ABC 执行之前,例如(在Unix 上)在fork() 之后但在execv() 之前(look at dup2() calls)。在Popen() 返回后使用相同的操作系统级别机制进行重定向为时已晚,但您可以手动模拟它。

“将p.stdin 重定向到终端的标准输入”,在进程运行时,调用shutil.copyfileobj(sys.stdin, p.stdin)。可能存在缓冲问题,并且子进程可能会在其标准输入之外读取,例如直接从 tty。见Q: Why not just use a pipe (popen())?

您可能想要pexpect's .interact() 之类的东西(未测试):

#!/usr/bin/env python
import pexpect  # $ pip install pexpect

child = pexpect.spawnu('ABC')
child.sendline('1 2 3')
child.interact(escape_character=None) # give control of the child to the user

【讨论】:

    【解决方案2】:

    您可以预先要求第四个整数,然后将其与其他 3 个一起发送:

    p = subprocess.Popen(['ABC'], stdin=subprocess.PIPE)
    fourth_int = raw_input('Enter the 4th integer: ')
    all_ints = '1 2 3 ' + fourth_int
    p.communicate(input=all_ints)
    

    【讨论】:

    • 在发送其他 3 个整数之前没有理由要求第 4 个整数:p.stdin.write('1 2 3\n'); fourth = raw_input('4th int: '); p.stdin.write(fourth); p.stdin.close()
    • @J.F.Sebastian - 你是对的。我的方法是完成工作的一种方式。这不是唯一的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-04
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    相关资源
    最近更新 更多