我调用一个运行可执行文件的子进程,输出类似于:
Header
some text
some text
--------------------------------
Progress:
*** | 30%
I want this line too
我想要最后三行,但不是前一行。进展自我更新,我也希望有。
我目前正在做:
print subprocess.call('program {options}'.format(options=options), shell=True)
有没有简单的方法来实现这一目标?
答案 0 :(得分:1)
call
方法是Popen
的包装器,它等待程序完成,这可能不是你想要的。相反,您需要使用Popen
并从中读取stdout
。
答案取决于您正在使用的程序,或更具体,它如何更新终端。这是一个解决方案,它可以让您了解如何实现这一目标。你可能需要调整它。
例如,在我的示例中,仅实际更新了进度条本身。您的示例可能会更新更多行...
#!/usr/bin/env python2
from __future__ import print_function
import subprocess
proc = subprocess.Popen(['./out.py'], shell=True,
stdout=subprocess.PIPE)
# Discard first 4 lines
for i in range(4): proc.stdout.readline()
# First set of output
output = ''.join([ proc.stdout.readline() for i in range(3) ])
print(output.strip())
print('\n\n')
# Only one line is updated now
while True:
output = proc.stdout.readline()
print(output.strip().replace('\x1b[1A', ''))
作为参考,这里是进度栏的out.py
#!/usr/bin/env python2
from __future__ import print_function
import time, sys
print('Header')
print('some text')
print('some text')
print('-' * 40)
print('Progress:')
print('')
print('I want this line too')
sys.stdout.write('\x1b[1A' * 2)
i = 1
while True:
if i > 40: break
print('\r', '*' * i, sep='')
sys.stdout.write('\x1b[1A')
sys.stdout.flush()
i += 1
time.sleep(2)
此外,您可能希望将subprocess
方法与列表一起使用,如下所示:
subprocess.call(['ls', '-l', dir], shell=True)
原因是列表中的参数将被转义,即使它们包含空格,换行符或任何其他意外字符,它们仍然可以工作。如果您使用shell=True
,这尤其危险。如果由于某种原因无法将参数作为列表传递,请务必使用shlex
模块。