我写了一个简单的脚本,它使用7zip来备份目录。一切正常,但现在我想添加一些图形反馈,添加一个进度条。我知道我可以用zenity
做到这一点,但是,无论我尝试什么,我似乎都无法让它发挥作用。
我正在使用fgrep
来找出何时压缩新文件("压缩"是 7zip 在屏幕上打印的每一行的第一个单词),以使条形增加。具体代码行如下:
7z a -t7z /home/user/Desktop/Backup.7z /home/user/Desktop/folder_to_backup -mx9 | fgrep Compressing | nl | awk '{print $1/$number_of_files*100}' | zenity --progress --percentage=0 --auto-close
运行此按钮将显示进度条,从 0 开始,但不显示进度:操作完成后,进度条突然跳到末尾。
我已经用谷歌搜索了一段时间,但我唯一发现的是zenity progress
似乎有一些问题:D任何帮助将不胜感激!
看起来您没有在输出中获取命令的进度,请在没有| zenity --progress --percentage=0 --auto-close
管道的情况下运行命令来检查它。
尝试这样的事情来获取输出,首先你需要apt-get install screen
你没有安装它:
screen -L bash -c '(while :; do tail ~/screenlog.0 | grep -o "[0-9]*%" | tail -1; done | zenity --progress --auto-close &); 7z a "output.zip" "/path/to/input"'
我将分解该命令最重要的部分:
- screen -L此标志告诉
screen
命令启动新会话并将所有终端输出记录到文件中,默认情况下~/screenlog.0
。 - bash -c COMMAND1生成一个子壳并在其中运行
COMMAND1
。 - (COMMAND2 &)生成另一个将在后台启动
COMMAND2
的子外壳。 - 而:;开始无限循环。
- 尾部文件阅读最后 10 行
FILE
. - grep -o仅打印匹配行的匹配(非空)部分。
- [0-9]*% 后跟 % 符号的任何数字系列。
- tail -1读取上一个管道命令的最后一行。
无需创建临时文件的解决方案
终于,在剧烈头痛和流鼻血之后,我得到了它......
线索是,交互式与非交互式缓冲: 交互式程序通常对其输出进行行缓冲;也就是说,他们写出每一行。非交互式程序会等到它们有一个完整的缓冲区,这可能是许多行输出。 现在,如果将非交互式程序通过管道传输到另一个程序,则第二个程序不会在第一个程序写出完整缓冲区之前获得其输入。
cd /home/user
export number_of_files=$(find folder_to_backup -type f | wc -l) && ( find folder_to_backup -print0 -type f -exec sh -c "7z a -t7z /path/to/Backup.7z {} -mx9 -bd | grep Compressing" ; | awk -W interactive -v x="$number_of_lines" '{printf "%dn", (NR*100/x)}' ) | zenity --progress --percentage=0 --auto-close
我可能需要解释一下:
cd/home/user您需要在 7z-Backup 中要目录结构的文件夹中进行 cd,否则 7z 不会在存档中放置目录结构。
export number_of_files=$(查找folder_to_backup -type f | wc -l)首先计算要压缩的文件,然后导出变量以供以后计算。
查找 folder_to_backup -print0 -type ffolder_to_backup必须是相对路径。(请参阅 1。
-exec sh -c "7z a -t7z/path/to/Backup.7z {} -mx9 -bd |grep 压缩" \;为每行启动一个子壳 查找输出并用管道执行 7Z 到 grep。
awk -W interactive -v x="$number_of_lines" '{printf "%d", (NR*100/x)}' 提示 awk 是交互式的(-W 交互式),传播之前导出的变量 (-v x="$number_of_lines"),最后计算并打印百分比 ('{printf "%d", (NR*100/x)')。
把所有这些都放在括号里,把烟斗放在禅意上。
问题不在于禅意。这是因为 7z 不写入标准输出。(可能使用 tput 或类似命令直接处理终端)。因此,您不能将其通过管道传输到另一个命令。
如果将命令重定向到文件,您实际上可以看到以下内容:
7z a -t7z /home/user/Desktop/Backup.7z /home/user/Desktop/folder_to_backup -mx9 | fgrep Compressing | nl | awk '{print $1}' > 7z.stdout
在我的 7Z 版本中,文件如下所示:
7-Zip [64] 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18
p7zip Version 9.20 (locale=en_CA.UTF-8,Utf16=on,HugeFiles=on,4 CPUs)
Scanning
Updating archive test.7z
Compressing test.file
Everything is Ok
您将需要一个带有代码的子shell来监视压缩,例如通过在完成时将文件大小与预期大小匹配,并回显百分比。将该子外壳放入正在执行压缩的子外壳中。访问 http://user.cavenet.com/rolandl 并查看ftp-user.txt以获取示例。Bash子壳非常方便!