如何为subprocess.call创建自定义输出流
我想通过定义我自己的输出流实时输出subprocess.call,但它似乎不工作。如何为subprocess.call创建自定义输出流
原因:我想运行一个子进程,并得到该呼叫的输出到标准输出(实时这样我就可以看剧本,看目前的进展),以及它记录到文件
子。潘岳:
import time
while True:
print("Things")
time.sleep(1)
mainprocess.py
import subprocess
import io
class CustomIO(io.IOBase):
def write(self, str):
print("CustomIO: %s"%str)
# logging to be implemented here
customio = CustomIO()
subprocess.call(["python3", "print_process.py"], stdout=customio)
但是当我运行这段代码我收到此错误信息:
Traceback (most recent call last):
File "call_test.py", line 9, in <module>
subprocess.call(["python3", "print_process.py"], stdout=customio)
File "/usr/lib/python3.4/subprocess.py", line 537, in call
with Popen(*popenargs, **kwargs) as p:
File "/usr/lib/python3.4/subprocess.py", line 823, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "/usr/lib/python3.4/subprocess.py", line 1302, in _get_handles
c2pwrite = stdout.fileno()
io.UnsupportedOperation: fileno
那么,任何人有任何线索,如果这是可能的?
我是否继承了错误的基类?
我是不是重载正确的方法?
还是我完全不合格,应该以完全不同的方式进行讨论?
如果您想处理子流程的输出,您需要通过stdout=subprocess.PIPE
。但是,call()
和run()
都将等到该过程完成后才能使用,因此无法使用这些功能实时处理它。
您需要使用subprocess.Popen
:
import subprocess as sp
def handle_output(output_line):
...
my_process = sp.Popen(["python3", "print_process.py"],
stdout=sp.PIPE,
universal_newlines=True) # changes stdout from bytes to text
for line in my_process.stdout:
handle_output(line)
my_process.wait()
更新:确保刷新输出缓冲区在你的孩子的过程:
while True:
print("Things", flush=True)
time.sleep(1)
这似乎并没有实时处理输出吗?当我运行它时,它会等待子流程在打印之前完成 – Bobbzorzen
我的歉意 - 出于某种原因,当我用'[“yes”]测试时它工作。查看更新。 – Phydeaux
不错,有没有办法做到这一点,而无需在子进程中添加刷新。在我的真实情况下,它不是一个python脚本,而是一个我无法控制的程序。 – Bobbzorzen
你需要用文件中指定和开放的流描述。 fileno
没有为io.IOBase
实现,因为这只是在内存中的数据流:
stdin
,stdout
和stderr
指定执行程序的标准 输入,标准输出和标准错误文件句柄,分别。 有效值为PIPE
,DEVNULL
,现有文件描述符( 正整数),现有文件对象和None
。PIPE
表示 应该创建一条给孩子的新管道。DEVNULL
表示 将使用专用文件os.devnull
。使用默认设置None
,不会发生重定向;
因此,您可能使用套接字,管道和打开文件作为stdout
,文件描述符作为stdout传递给子进程。虽然我没有用subprocess.Popen
套接字,但我希望它们能够工作,我相信这里重要的是该子文件描述符,而不是文件描述符指向的对象类型。
子过程期望一个真正的文件对象与真正的os文件描述符,尝试PIPE – georgexsh