Python-子流程命令的实时输出
我正在使用python脚本作为水动力代码的驱动程序。是时候运行模拟了,我subprocess.Popen
用来运行代码,将stdout
和stderr
的输出收集到subprocess.PIPE---
中,然后我可以打印(并保存到日志文件中)输出信息,并检查是否有错误。问题是,我不知道代码是如何进行的。如果我直接从命令行运行它,它将为我提供有关其迭代次数,时间,下一时间步长等的输出。
有没有办法既存储输出(用于日志记录和错误检查),又产生实时流输出?
我的代码的相关部分:
ret_val = subprocess.Popen( run_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True )output, errors = ret_val.communicate()
log_file.write(output)
print output
if( ret_val.returncode ):
print "RUN failed\n\n%s\n\n" % (errors)
success = False
if( errors ): log_file.write("\n\n%s\n\n" % errors)
最初,我是run_command
通过管道传递tee文件,以便将副本直接发送到日志文件,并且流仍直接输出到终端-但是那样,我无法存储任何错误(据我所知)。
编辑:
临时解决方案:
ret_val = subprocess.Popen( run_command, stdout=log_file, stderr=subprocess.PIPE, shell=True )while not ret_val.poll():
log_file.flush()
然后,在另一个终端中,运行tail -f log.txt(st log_file = 'log.txt')
。
回答:
你可以通过两种方法执行此操作,或者通过从read
或readline
函数创建迭代器,然后执行以下操作:
import subprocessimport sys
with open('test.log', 'w') as f: # replace 'w' with 'wb' for Python 3
process = subprocess.Popen(your_command, stdout=subprocess.PIPE)
for c in iter(lambda: process.stdout.read(1), ''): # replace '' with b'' for Python 3
sys.stdout.write(c)
f.write(c)
要么
import subprocessimport sys
with open('test.log', 'w') as f: # replace 'w' with 'wb' for Python 3
process = subprocess.Popen(your_command, stdout=subprocess.PIPE)
for line in iter(process.stdout.readline, ''): # replace '' with b'' for Python 3
sys.stdout.write(line)
f.write(line)
或者,你可以创建reader
和writer
文件。将传递writer
到Popen
并从中读取reader
import ioimport time
import subprocess
import sys
filename = 'test.log'
with io.open(filename, 'wb') as writer, io.open(filename, 'rb', 1) as reader:
process = subprocess.Popen(command, stdout=writer)
while process.poll() is None:
sys.stdout.write(reader.read())
time.sleep(0.5)
# Read the remaining
sys.stdout.write(reader.read())
这样,你就可以将数据写入test.log
和标准输出中。
文件方法的唯一优点是你的代码不会被阻塞。因此,你可以同时做任何你想做的事,并reader以不阻塞的方式随时阅读。当使用PIPE,read
和readline
功能将阻塞,直到任一个字符被写入到管或线被分别写入到管道。
以上是 Python-子流程命令的实时输出 的全部内容, 来源链接: utcz.com/qa/429162.html