我有一个从stderr读取的c程序(我不是作者)。我用subprocess.Popen调用它,如下所示。有没有办法写入子进程的stderr。
proc = subprocess.Popen(['./std.bin'],stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
答案 0 :(得分:2)
是的,也许,但您应该注意写入子流程的标准输出或标准错误输出的不规则性。绝大多数进程只写入这些进程,几乎没有进程真正尝试读取(因为几乎在所有情况下都没有任何东西可读)。
您可以尝试打开套接字并将其作为stderr
参数提供。
您最想要做的事情恰恰相反,从子进程中读取subprocess.PIPE
(子进程写入,您阅读)。这可以通过将其设置为stderr
然后访问子流程的proc subprocess(['./std.bin'], stderr=subprocess.PIPE)
for l in proc.stderr:
print(l)
属性来完成:
stdin
请注意,您可以将stdout
,stderr
和subprocess.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。希望它能回答你的问题。