如何打印和捕获7zip';从python执行时的s%进度标记?

如何打印和捕获7zip';从python执行时的s%进度标记?,python,7zip,Python,7zip,当7zip从命令行运行时,它将使用一系列“%”符号打印进度条 我想在Python中执行7zip时捕获并打印这个进度条。 我该怎么做 我当前使用的Python代码: 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()[

当7zip从命令行运行时,它将使用一系列“%”符号打印进度条

我想在Python中执行7zip时捕获并打印这个进度条。 我该怎么做

我当前使用的Python代码:

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

您需要的是sys.stdout.flush()

但是,您可能需要在单独的线程上执行flush,因为在Popen中的底层进程完成之前,主线程可能会被阻塞

编辑:使用Brian的答案来帮助(并避免多线程),我设想一个如下的解决方案:

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)
来自(我的):

从stdout和stderr读取数据,直到到达文件末尾等待进程终止。

考虑改用:


当标准输出被重定向时,我发现7za禁止进度输出。
所以,我写了一个补丁
“sopg”选项启用进度输出,即使标准输出被重定向或管道化。


$7za x-sopg..7z

您的问题完全不清楚。什么“百分比”?现在清楚了吗?我指的是一个命令进度百分比,比如创建一个归档文件或删除它,抱歉英语不好,不清楚。您需要给出一个命令输出的示例。如果不显示百分比的外观和周围的文本类型,没有人可以说如何获取百分比。问题是当我使用Popen运行7z命令行时,它只会在完成后返回最终输出,当命令运行时无法获得任何输出
tar cf-directory | pv--size$(du-sb directory | cut-f1)| 7z a-si目录。7z
在*nix上显示进度条。当我在线程中使用communicate时,python停止该行!不要退回任何东西output@SepehrMohammadPour,省略对
通信的调用,这不是必需的。
pipe=Popen('7za.exe…
部件已经调用了
7za
communicate
将等待
7za
完成,但
poll
将指示是否完成。Flush强制缓冲输出为标准输出。请参阅。作者的评论如下。此标志是否仍处于活动状态?我在Windows 10,7zip 19.00上,正在尝试
-sopg
和get
开关太长:-sopg
。我从文档中了解到
-bsp1
应该可以工作,但它对我没有任何作用:/(Python脚本没有掌握进度)上面的此修补程序未合并到官方7-zip中。如果您想使用此修补程序,您需要自行合并和生成。您知道在Windows上还可以做什么吗?如果您不介意使用在我的appveyor上生成的二进制文件,则上面的链接上存在已修补的7za.exe。我不知道如何通过按原样使用官方二进制文件来解决此问题。
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