python subprocess.Popen - 写入stderr

时间:2015-10-23 05:13:53

标签: python subprocess

我有一个从stderr读取的c程序(我不是作者)。我用subprocess.Popen调用它,如下所示。有没有办法写入子进程的stderr。

proc = subprocess.Popen(['./std.bin'],stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

3 个答案:

答案 0 :(得分:2)

是的,也许,但您应该注意写入子流程的标准输出或标准错误输出的不规则性。绝大多数进程只写入这些进程,几乎没有进程真正尝试读取(因为几乎在所有情况下都没有任何东西可读)。

您可以尝试打开套接字并将其作为stderr参数提供。

您最想要做的事情恰恰相反,从子进程中读取subprocess.PIPE(子进程写入,您阅读)。这可以通过将其设置为stderr然后访问子流程的proc subprocess(['./std.bin'], stderr=subprocess.PIPE) for l in proc.stderr: print(l) 属性来完成:

stdin

请注意,您可以将stdoutstderrsubprocess.PIPE中的多个指定为subprocess.PIPE。这将意味着它们将连接到同一个管道(communicate不是确实文件,而只是一个占位符来指示应该创建管道)。如果你这样做,你应该注意避免死锁,这可以通过使用subprocess方法来完成(你可以检查communicate模块的来源,看看var url = "http://someurl/SERVICE"; var username = "username"; var password = "password"; var oModel = new sap.ui.model.odata.ODataModel(url, true, username, password); 如果你想自己做的话。)

答案 1 :(得分:2)

如果子进程从stderr读取(注意:通常stderr打开输出):

#!/usr/bin/env python
"""Read from *stderr*, write to *stdout* reversed bytes."""
import os

os.write(1, os.read(2, 512)[::-1])

然后你可以提供一个伪tty(以便所有流指向同一个地方),以便与孩子一起工作,就好像它是一个普通的子流程一样:

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

child = pexpect.spawnu(sys.executable, ['child.py'])
child.sendline('abc') # write to the child
child.expect(pexpect.EOF)
print(repr(child.before))
child.close()

输出

u'abc\r\n\r\ncba'

你也可以use subprocess + pty.openpty() instead pexpect

或者您可以编写特定于奇怪的stderr行为的代码:

#!/usr/bin/env python
import os
import sys
from subprocess import Popen, PIPE

r, w = os.pipe()
p = Popen([sys.executable, 'child.py'], stderr=r, stdout=PIPE,
          universal_newlines=True)
os.close(r)
os.write(w, b'abc') # write to subprocess' stderr
os.close(w)
print(repr(p.communicate()[0]))

输出

'cba'

答案 2 :(得分:0)

for line in proc.stderr:
    sys.stdout.write(line)

这是编写子进程的stderr。希望它能回答你的问题。