我有一个python脚本,作为其中的一部分,运行perl脚本。我正在使用stdout
模块执行并捕获stderr
和subprocess
;伪代码是:
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脚本的stdout特征相匹配的示例,并且实际输出(我无法发布)大约是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
写入文件,但我想避免这种情况(我相信该方法不再使用了。)
答案 0 :(得分:0)
您可以在while循环之外定义数据,并在最后将最后一个状态写入文件。这样它只会将数据保存的最后状态更新写入文件,这将避免不断覆盖文件的最后状态。
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 = ''
data = ''
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()
p.stdout.close()
with open(fname, 'w') as log:
log.write(data)