[英]How can I capture the output of a child process spawned by a piped process?
I want to continuously monitor a piped process and print its stdout
and stderr
as it comes in ( I'm not interested in getting the whole output all at once after it exited ). 我想不断监视管道进程并在其进入时打印其stdout
和stderr
(我对退出后立即全部获取全部输出不感兴趣)。 The problem is that the piped process spawns an other child process, and the stdout
and stderr
of that spawned process is not accessible using the pipes of the original process. 问题在于,管道处理产生了另一个子进程,并且使用原始进程的管道无法访问该产生的进程的stdout
和stderr
。
Namely I want to run a python program in this way, so the piped process is the python interpreter, but python interpreter spawns the running of the python program in an other subprocess, so I can't obtain the output of that ( the actual program output ). 也就是说,我想以这种方式运行python程序,因此管道进程是python解释器,但是python解释器会在另一个子进程中生成python程序的运行,因此我无法获得该输出(实际程序输出)。 If there is an error starting the program, I can get this because this is printed to original python interpreter's stderr
. 如果启动程序时出错,我可以得到它,因为它被打印到原始python解释器的stderr
。 But normal stdout
from the actual program is lost for me. 但是实际程序中的正常stdout
对我来说却丢失了。
I'm using subprocess.Popen
. 我正在使用subprocess.Popen
。
Edit: A commenter asked for a code sample, I don't think this adds to much, but here is my code ( PopenProcess
is an intelligent wrapper class for subrpocess.Popen
but does nothing extraordinary ): 编辑:一个评论者问了代码示例,我不认为这会增加很多,但这里是我的代码( PopenProcess
是一种智能包装类subrpocess.Popen
但确实也没什么特别的):
class BTask:
def __init__(self, name, cmds, color = "NONE"):
self.name = name
self.cmds = cmds
self.color = color
self.proc = None
def procreadline(self, sline):
print(ANSI[self.color] + self.name + ANSI["ENDC"] + " > " + ANSI[self.color] + sline)
def procreaderror(self, sline):
print(ANSI[self.color] + self.name + ANSI["BRIGHTWHITE"] + " ! " + ANSI["BRIGHTRED"] + sline)
def run(self):
print(ANSI["GREEN"])
print("running task: {} {}".format(ANSI["BRIGHTGREEN"], self.name))
pargs = []
if len(self.cmds) > 1:
pargs = self.cmds[1:]
print(ANSI[self.color])
self.proc = PopenProcess(
self.cmds[0],
self.procreadline,
read_error_callback = self.procreaderror,
proc_args = pargs,
ignore_cwd = True
)
def kill(self):
print(ANSI["RED"])
print("killing task: {} {}".format(ANSI["BRIGHTRED"], self.name))
self.proc.kill()
def is_alive():
return self.proc.is_alive()
As a piped process instead of 作为管道处理而不是
subprocess.Popen(['python', 'myprog.py'])
one should use 一个应该使用
subprocess.Popen(['python', '-u', 'myprog.py'])
Then it works. 然后就可以了。
The problem was with buffered output, and -u
switch turns this off ( allows unbuffered output ). 问题出在缓冲输出上,而-u
开关将其关闭(允许无缓冲输出)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.