【问题标题】:Communication with process using pipes in Python在 Python 中使用管道与进程通信
【发布时间】:2015-02-02 12:54:12
【问题描述】:

我有一个进程,我可以像这样在命令行上与之通信:

% process -
input
^D^D
output

所以:我开始这个过程,输入一些输入,然后按两次 Ctrl-D 后,我得到了输出。 我想围绕这个过程制作一个 Python 包装器。我创建了这个:

from subprocess import Popen, PIPE

p = Popen('process -', stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
while True:
        input = raw_input('Enter input: ')
        p.stdin.write(input)
        p.stdin.close()
        p.wait()
        output = p.stdout.read()
        print output

这第一次有效,但之后我得到:

Traceback (most recent call last):
  File "test.py", line 7, in <module>
    p.stdin.write(input)
ValueError: I/O operation on closed file

是否有另一种方法可以在不关闭文件的情况下与此进程进行交互?

【问题讨论】:

  • 问题有点复杂。正如我现在所看到的,您必须删除那些结束行,添加 p.stdin.flush() 并捕获 SIGINT 信号。当它发生时,您必须将其传递给子进程并然后 p.wait()(或更好的p.communicate()),打印输出并关闭进程。

标签: python pipe subprocess


【解决方案1】:

p.wait() 将等到子进程退出后再返回,因此在脚本的第二次迭代中,p 已经退出(因此已关闭 p.stdin)。

【讨论】:

    【解决方案2】:

    如果您包装的过程在第一个输出之后结束,则通信将失败到第二个。由于所有管道(标准输入和标准输出)都将关闭。因此错误:

    ValueError: I/O operation on closed file.

    每次您尝试将输入发送到被包装的进程时,都必须期望输入和管道必须打开。

    另一方面,Thomas 在他的回答中说,p.wait() 不是重复输入/输出策略的方法。

    你也不能使用subprocess.Popen.communicate(),因为它在内部调用subprocess.Popen.wait()

    您可以尝试使用p.stdin.writep.stdout.read 在这里您有一篇关于该主题的好文章:Writing to a python subprocess pipe

    【讨论】:

      【解决方案3】:

      模拟 shell 会话:

      $ process -
      input
      ^D^D
      output
      

      在 Python 中,使用 check_output():

      #!/usr/bin/env python3
      from subprocess import check_output
      
      out = check_output(['process', '-'], input='input\n', universal_newlines=True)
      print(out, end='')
      

      Ctrl+D 被 Unix 终端识别为 EOF(终止输入)($ stty -a -- 在输出中查找 eof = ^Dicanon)。如果您需要键入 Ctrl+D 两次(at the beginning of a line);它可能表示process 程序中的错误,例如"for line in sys.stdin: doesn't notice EOF the first time" Python bug

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-01
        • 1970-01-01
        • 2012-08-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多