【发布时间】:2016-03-31 19:02:26
【问题描述】:
我有一个 python 脚本,作为它的一部分,它运行一个 perl 脚本。我正在使用subprocess 模块执行和捕获stdout 和stderr;伪代码是:
import subprocess as sp
import sys
perl_script='/usr/.../foo.pl'
p = sp.Popen(perl_script,stdout=sp.PIPE,stderr=sp.PIPE)
fname='test.log'
shell_out=True
text = ''
with open(fname, 'w') as log:
while True:
data = p.stdout.read(1)
if data == '' and p.poll() != None:
break
if data != '':
if shell_out is True:
sys.stdout.write(data)
sys.stdout.flush()
log.write(data)
p.stdout.close()
对于循环的每次迭代,数据似乎是单个字符串字符。
我遇到的问题是这个 perl 脚本显示了一个被它覆盖的进度条;类似:
[#####.....] 50%
每 5% 更新一次。因此,我写入的日志文件最终会包含以下内容:
[#.........] 5% [##........] 10% [###.......] 15%
等等。
有没有一种方法或方式可以让我覆盖日志文件中的前一行,或者我唯一的选择是捕获所有文本,尝试修改它,然后将其写入日志文件?
编辑:我认为我给出的示例的简单性质可能无法说明整个故事。这个 perl 脚本有多个进度条(每个任务一个)并输出我想要记录的附加信息。更详细的例子是:
NOTICE: one or more of things did stuff and you probably want to take note of it
writing the foo file . . .
writing things . . . [####################] 100%
writing stuff . . . [####################] 100%
writing items . . . [####################] 100%
done
creating other files...
done
请记住,上面的输出是一个与这个 perl 脚本的标准输出特性相匹配的示例,并且实际输出(我无法发布)大约是 100 行左右。
最后,感谢格式化帮助:)
编辑#2:当stdout 被捕获时,我已经放弃尝试写入日志文件,而是将stdout 存储在一个变量中,并在脚本完成后写入日志文件。剩下的唯一问题是如何正确格式化字符串,以便正确写入日志文件。更新后的伪代码为:
import subprocess as sp
import sys
tg_post='/usr/.../foo.pl'
p = sp.Popen(tg_post,stdout=sp.PIPE)
text = ''
fname='test.log'
shell_out=True
while True:
data = p.stdout.read(1)
if data == '' and p.poll() != None:
break
if data != '':
if shell_out is True:
sys.stdout.write(data)
sys.stdout.flush()
text += data
p.stdout.close()
text = text.split('\r')
with open(fname, 'w') as log:
log.write(text)
目前,此代码为每个状态栏的每个百分比生成一行。我想我可以遍历文本中的每个索引(拆分后)并删除有# 而不是100% 的索引,但我希望有更强大的东西。如果我print text(拆分后),我会在屏幕上得到我想要的。我知道可以使用print 写入文件,但我想避免这种情况(我相信不再使用该方法)。
【问题讨论】:
-
为什么要覆盖日志文件中的行?
-
@nathan.meadows - 如果我不覆盖日志文件中的行,那么它不是一个易于阅读的 ~100 行文件,而是一个 ~50 行文件,其中一些行大约有 1600 个字符。
标签: python