python - 在shell stdout存活时捕获子进程的stderr

1 投票
2 回答
1299 浏览
提问于 2025-04-16 14:15

我正在尝试做一些事情:

-python process captures stderr of multiple subprocesses to watch the subprocesses
-each subprocess runs on the separate window displaying stdout. 

当我使用 Popen(command,stderr = fp4tempfile) 时,

(good) the python process can capture stderr of the subprocesses
(bad ) the subprocess shells stop displaying stdout.

当我使用 Popen(command) 时,

(good) each subprocess shells displays stdout (as well as stderr, which does not matter for me), 
(bad ) the python process cannot capture stderr. 

我想要两个“好”的结果。我该怎么做呢?谢谢!
(目前,我在使用python3.2,在windows7上开发)

这是用python写的父进程的代码:

import os,subprocess
import time
fpws = []
fprs = []

def run_command(command):
    <specifying a file to write -- skipped>
    fpw = open(ftempname,'w')
    fpr = open(ftempname,'r')
    #cmd_redirect = "%s 2>%s" % (command,ftempname)#didnt do anything
    #starting a sub-program:
    pp = subprocess.Popen(command,stderr = fpw) #++
    #pp = subprocess.Popen(command)             #@@
    fpws.append(fpw)
    fprs.append(fpr)    

def watch_program():
    while True: #running forever for simplfication
        for fpr in  fprs:
            outchunk = fpr.read()
            <do something for subprocesses stderr -- skipped>
            time.sleep(1.0)

if __name__ == '__main__':
    cmd1 = '(path to program1)'
    cmd2 = '(path to program2)'
    run_command(cmd1)  #kicking cmd1
    run_command(cmd2)  #kicking cmd2
    watch_program()          #hearing stderr msg from the other process

注意:在子进程那边,会根据需要调用 fflush(stdout) 和 fflush(stderr)。

2 个回答

0

I82Much,非常感谢你的回答和评论。

是的,你关于stderr的评论完全正确。我是在Windows 7上开发的。在Linux(ubuntu10)上,下面的代码就能顺利运行:

    cmd_line4sub = command + ' 2> ' + ftempname
    pp = subprocess.Popen(['/usr/bin/xterm','-e',cmd_line4sub],stderr = fpw)

这段代码会打开新的命令行窗口,并打印出子进程的标准输出(stdout)。而父进程则会捕获子进程的标准错误输出(stderr)。这是我最初的目标。

如果我能搞定在Windows上怎么做,我会把我的解决方案分享出来;)

(我和提问者是同一个用户,但我无法把它们合并成同一个账户…)

0

我还没测试过这个,不过你能这样做吗

import sys

pp = subprocess.Popen(command, stderr = fpw, stdout = sys.stdout)

撰写回答