问题
When 7zip runs from the command line, it will print a progress bar using a series of '%' symbols.
I'd like to both capture and print this progress bar when executing 7zip from within Python. How do I do this?
The Python code I'm currently using:
from subprocess import Popen, PIPE
pipe = Popen('7za.exe a -tgzip "e:\\backup\\sch Testerr 2012 06 23 17-27.gzip" "E:/archiv"' , stdout=PIPE)
text = pipe.communicate()[0]
print text
回答1:
What you want is sys.stdout.flush().
However, you may need to execute flush on a separate thread since the main thread is probably blocked until the underlying process in Popen is complete.
Edit: Using Brian's answer to help (and to avoid multi-threading), I'd envisage a solution like this:
from subprocess import Popen, PIPE
pipe = Popen('7za.exe a -tgzip "e:\\backup\\sch Testerr 2012 06 23 17-27.gzip" "E:/archiv"' , stdout=PIPE)
# Assuming Python thread continues after POpen invoke (but before 7za is finished)
while (not pipe.poll()):
sys.stdout.flush()
time.sleep(1)
回答2:
From communicate (emphasis mine):
Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate.
Consider using poll instead:
from subprocess import Popen, PIPE
pipe = Popen('7za.exe a -tgzip "e:\\backup\\sch Testerr 2012 06 23 17-27.gzip" "E:/archiv"', stdout=PIPE)
while True: # Feeling fancy? add a timeout condition here...
if pipe.poll():
break
# consider reading from stdin and printing as your needs indicate
回答3:
I found 7za suppress progress output when stdout is redirected.
So, I wrote a patch.
'sopg' option enables progress output even when stdout is redirected or piped.
https://github.com/photom/p7zip/commit/2baacd6c354fbde19ebc83d185e73f6d9bd62517
$ 7za x -sopg ..7z
来源:https://stackoverflow.com/questions/11270524/how-to-print-and-capture-7zips-progress-markers-when-executing-from-python