使用stdin从subprocess.Popen.communicate()断开管道

时间:2010-01-14 21:55:49

标签: python

使用subprocess.Popen.communicate()时遇到一个奇怪的问题。对于后台,我想从我的python脚本执行一个应用程序。当我从命令行运行程序时,我这样做(UNIX):

$ echo "input text" | /path/to/myapp

从我的脚本中,我还想将输入传递给应用程序。所以,我尝试了以下内容。但是当我尝试使用communic()发送输入时出现“管道损坏”错误:

>>> cmd = ['/path/to/myapp']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
>>> out,err = p.communicate('input text')
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python2.5/subprocess.py", line 670, in communicate
    return self._communicate(input)
  File "/usr/lib/python2.5/subprocess.py", line 1223, in _communicate
    bytes_written = self._write_no_intr(self.stdin.fileno(), buffer(input, input_offset, 512))
  File "/usr/lib/python2.5/subprocess.py", line 1003, in _write_no_intr
    return os.write(fd, s)
OSError: [Errno 32] Broken pipe

为了使事情变得更奇怪,如果我遗漏输入数据,我不会有任何错误。但是,这并不是一个好的解决方法,因为应用程序需要输入才能工作。

>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
>>> out,err = p.communicate()
>>> print out
[error from myapp regarding lack of input]

知道我缺少什么吗?

1 个答案:

答案 0 :(得分:3)

您的观察结果表明myapp正在终止而没有阅读(所有)输入。对myapp一无所知,这很难确认,但请考虑例如

$ echo 'hello world' | tr 'l' 'L'
heLLo worLd

现在...

>>> cmd = ['/usr/bin/tr']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE)
>>> out,err = p.communicate('hello world')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.5/subprocess.py", line 668, in communicate
    return self._communicate(input)
  File "/usr/lib/python2.5/subprocess.py", line 1218, in _communicate
    bytes_written = self._write_no_intr(self.stdin.fileno(), buffer(input, input_offset, 512))
  File "/usr/lib/python2.5/subprocess.py", line 997, in _write_no_intr
    return os.write(fd, s)
OSError: [Errno 32] Broken pipe

,因为...

>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
>>> /usr/bin/tr: missing operand
Try `/usr/bin/tr --help' for more information.

如果我们修复错误:

>>> cmd = ['/usr/bin/tr', 'l', 'L']
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
>>> out,err = p.communicate('hello world')>>> print out
heLLo worLd
>>> print err
None

......它修复了一切。如果省略stderr重定向会发生什么 - 你是否真的看到来自myapp的任何错误消息......?