【问题标题】:python subprocess.Popen - write to stderrpython subprocess.Popen - 写入标准错误
【发布时间】:2015-10-23 05:13:53
【问题描述】:

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

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

【问题讨论】:

  • 错误。 stderr 是一个输出通道。为什么要求从中读取?你是不是想说点别的?
  • @JLPeyret 我不是那个 c 程序的作者。顺便说一句,那个程序正在运行。
  • 不用担心。这是一个非常不寻常的请求,需要在每个人都粘贴到通常的 read-from-stderr 食谱之前进行确认。

标签: python subprocess


【解决方案1】:

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

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

您最可能想要做的是相反的事情,从子进程中读取stderr(子进程写入,您读取)。这可以通过将其设置为subprocess.PIPE 然后访问子进程的stderr 属性来完成:

proc subprocess(['./std.bin'], stderr=subprocess.PIPE)

for l in proc.stderr:
     print(l)

请注意,您可以将stdinstdoutstderr 中的多个指定为subprocess.PIPE。这将意味着它们将连接到同一个管道(subprocess.PIPE 不是实际文件,而只是一个指示应该创建管道的占位符)。如果你这样做,但你应该注意避免死锁,例如,这可以通过使用 communicate 方法来完成(你可以检查 subprocess 模块的源代码,看看 communicate 做了什么,如果你想做自己动手)。

【讨论】:

    【解决方案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'
    

    【讨论】:

      【解决方案3】:
      for line in proc.stderr:
          sys.stdout.write(line)
      

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

      【讨论】:

        猜你喜欢
        • 2011-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-03
        • 2011-08-10
        • 2016-05-31
        • 1970-01-01
        • 2021-03-05
        相关资源
        最近更新 更多