6

我的 python 代码生成子进程,并打印出 stdout 和 stderr 消息。我需要以不同的方式打印它们。

我有以下代码来生成子进程并从中获取标准输出结果。

cmd = ["vsmake.exe", "-f"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
for line in iter(p.stdout.readline, ''):
    print line,
    sys.stdout.flush()
    pass
p.wait()

如何修改代码以检查子进程是否也通过 stderr 打印出消息?

添加

一旦子进程打印出一些东西,我就需要打印出 stderr 和 stdout。它是跨平台实现,所以它应该在 Mac/Linux/PC 上运行。

4

2 回答 2

7
p = Popen(cmd, bufsize=1024,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
p.stdin.close()
print p.stdout.read() #This will print the standard output from the spawned process
print p.stderr.read() #This is what you need, error output <-----

所以基本上错误输出被重定向到stderr管道。

如果您需要更多实时的东西。我的意思是,一旦生成的进程向stdout orstderr 打印了一些东西,就会打印行,那么你可以执行以下操作:

def print_pipe(type_pipe,pipe):
    for line in iter(pipe.readline, ''):
         print "[%s] %s"%(type_pipe,line),

p = Popen(cmd, bufsize=1024,
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)

t1 = Thread(target=print_pipe, args=("stdout",p.stdout,))
t1.start()
t2 = Thread(target=print_pipe, args=("stderr",p.stderr,))
t2.start()

#optionally you can join the threads to wait till p is done. This is avoidable but it 
# really depends on the application.
t1.join()
t2.join()

在这种情况下,每次将一行写入 或 时,都会打印两个stdout线程stderr。该参数type_pipe仅在打印行以了解它们是否来自stderr或时进行区分stdout

于 2011-01-26T14:26:18.550 回答
1

独立于平台执行此操作的最简单方法是使用线程(不幸的是)。这是一些示例代码:

def redirect_to_stdout(stream):
    for line in stream:
        sys.stdout.write(line)
        sys.stdout.flush()

cmd = ["vsmake.exe", "-f"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stderr_thread = threading.Thread(target=redirect_to_stdout, args=(p.stderr,))
stderr_thread.start()
redirect_to_stdout(p.stdout)
p.wait()
stderr_thread.join()
于 2011-01-26T14:58:53.547 回答