How to print and capture 7zip's % progress mar

2019-04-10 17:44发布

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

标签: python 7zip
3条回答
我欲成王,谁敢阻挡
2楼-- · 2019-04-10 18:01

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楼-- · 2019-04-10 18:08

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)
查看更多
萌系小妹纸
4楼-- · 2019-04-10 18:14

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

查看更多
登录 后发表回答