如何使用自定义文件类对象作为子进程stdout / stderr?

时间:2014-01-10 02:21:38

标签: python subprocess

考虑这段代码,产生subprocess.Popen。我希望写入子进程“stdoutstderr以转到我的自定义文件对象的.write()方法,但事实并非如此。

import subprocess

class Printer:

    def __init__(self):
        pass

    def write(self, chunk):
        print('Writing:', chunk)

    def fileno(self):
        return 0

    def close(self):
        return

proc = subprocess.Popen(['bash', '-c', 'echo Testing'], 
                        stdout=Printer(),
                        stderr=subprocess.STDOUT)
proc.wait()

为什么.write()方法没有使用,在这种情况下指定stdout=参数有什么用?

2 个答案:

答案 0 :(得分:2)

根据the documentation

  

stdin,stdout和stderr分别指定执行程序的标准输入,标准输出和标准错误文件句柄。有效值为 PIPE,DEVNULL,现有文件描述符(正整数),现有文件对象和无

使用subprocess.PIPE

proc = subprocess.Popen(['bash', '-c', 'echo Testing'], 
                        stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT)
print('Writing:', proc.stdout.read())
# OR  print('Writing:', proc.stdout.read().decode())

答案 1 :(得分:0)

不直接。也许将来的某些Python版本将支持将类似文件的对象转换为某种自动填充管道,但是其症结在于,子进程需要访问文件句柄,而该文件句柄无需以某种方式调用Python代码即可读取。这意味着它必须在操作系统级别上起作用,这意味着它仅限于几种可能性:

  • 从父进程继承stdin(在stdin=None时发生)
  • 从文件中获取输入(stdin是文件或整数文件句柄时发生)
  • 从管道中获取输入(在stdin=subprocess.PIPE时发生)

使用类似文件的对象意味着您将必须自己读取数据,然后通过管道将其提供。

例如:

proc = subprocess.Popen(['sha256sum', '-'], stdin=subprocess.PIPE)
while True:
    chunk = filelike.read(BLOCK_SIZE)
    proc.stdin.write(chunk)
    if len(chunk) < BLOCK_SIZE:
        break
proc.wait()