将subprocess.Popen中的stdout保存到文件中,并在文件中写入更多内容

我正在写一个Python脚本,它使用subprocess.Popen执行两个程序(从编译的C代码),每个程序生成标准输出。 脚本获取该输出并将其保存到文件中。 由于输出有时足够大以致无法覆盖subprocess.PIPE,导致脚本挂起,所以我直接将stdout发送到日志文件。 我想让我的脚本写入文件的开始和结尾,以及两个subprocess.Popen调用之间。 但是,当我查看我的日志文件时,从脚本写入日志文件的所有内容都集中在文件顶部,其后是所有可执行文件stdout。 我怎样才能交叉我的文字添加到文件?

def run(cmd, logfile): p = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=logfile) return p def runTest(path, flags, name): log = open(name, "w") print >> log, "Calling executable A" a_ret = run(path + "executable_a_name" + flags, log) print >> log, "Calling executable B" b_ret = run(path + "executable_b_name" + flags, log) print >> log, "More stuff" log.close() 

日志文件有:调用可执行文件A调用可执行文件B更多的东西[…来自两个可执行文件…标准输出…]

例如,在调用Popen之后,有没有办法将A的stdout刷新到日志? 还有一件事可能是相关的:可执行文件A然后启动,然后在B打印完东西并完成之后,A打印更多的东西并结束。

我在RHE Linux上使用Python 2.4。

Solutions Collecting From Web of "将subprocess.Popen中的stdout保存到文件中,并在文件中写入更多内容"

您可以在每个Popen对象上调用.wait()以确保完成,然后调用log.flush()。 也许这样的事情:

 def run(cmd, logfile): p = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=logfile) ret_code = p.wait() logfile.flush() return ret_code 

如果您需要在外部函数中与Popen对象进行交互,则可以将.wait()调用移动到那里。

我说只是保持简单。 伪代码基本逻辑:

 write your start messages to logA execute A with output to logA write your in-between messages to logB execute B with output to logB write your final messages to logB when A & B finish, write content of logB to the end of logA delete logB 

在继续之前,您需要等到过程完成。 我也转换了代码使用上下文管理器,这是更清洁。

 def run(cmd, logfile): p = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=logfile) p.wait() return p def runTest(path, flags, name): with open(name, "w") as log: print >> log, "Calling executable A" a_ret = run(path + "executable_a_name" + flags, log) print >> log, "Calling executable B" b_ret = run(path + "executable_b_name" + flags, log) print >> log, "More stuff" 

据我了解, A程序等待B做它的事情,只有B退出后, A才退出。

如果B可以在没有运行的情况下启动,则可以按相反的顺序启动进程:

 from os.path import join as pjoin from subprocess import Popen def run_async(cmd, logfile): print >>log, "calling", cmd p = Popen(cmd, stdout=logfile) print >>log, "started", cmd return p def runTest(path, flags, name): log = open(name, "w", 1) # line-buffered print >>log, 'calling both processes' pb = run_async([pjoin(path, "executable_b_name")] + flags.split(), log) pa = run_async([pjoin(path, "executable_a_name")] + flags.split(), log) print >>log, 'started both processes' pb.wait() print >>log, 'process B ended' pa.wait() print >>log, 'process A ended' log.close() 

注意:在主进程中调用log.flush()进程中的文件缓冲区没有影响。

如果子进程为标准输出使用块缓冲,那么你可以尝试使用pexpect,pty或stdbuf更早地刷新它们(它假定进程使用交互式运行时的行缓冲,或者使用C stdio库进行I / O) 。