如何发送值到Zenity进度条

我写了一个简单的脚本,使用7zip来备份一个目录。 一切正常,但现在我想添加一些graphics反馈,添加一个进度条。 我知道我可以做到这一点,但无论我尝试什么,我似乎都无法做到。

我正在使用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开始显示,但没有显示进度:操作完成后,栏会突然跳到结尾。

我已经search了一段时间,但唯一的事情是我发现, zenity progress似乎有一些问题:D任何帮助将不胜感激!

看起来你没有得到你的输出命令的进展,通过运行你的命令没有| zenity --progress --percentage=0 --auto-close检查出来 | 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"' 

我将分解命令中最重要的部分:

  1. screen -L该标志告诉screen命令启动一个新的会话,并将所有终端输出记录到一个文件,默认为~/screenlog.0
  2. bash -c COMMAND1生成一个子shell并在其中运行COMMAND1
  3. (COMMAND2&)产生另一个将在后台启动COMMAND2子shell。
  4. 同时: 开始一个无限循环。
  5. tail FILE读取FILE的最后10行。
  6. grep -o仅打印匹配行的匹配(非空)部分。
  7. [0-9] *%任何系列的数字,后跟%符号。
  8. tail -1读取前一个管道命令的最后一行。

解决方案没有临时文件创建

最后,我得到了它后,头痛和鼻血一些…

线索是交互式vs非交互式缓冲:交互式程序通常将输出缓冲到行; 即他们写出每一行。 非交互程序等待,直到他们有一个完整的缓冲区,这可能是许多行的输出。 现在,如果您将一个非交互式程序传递给另一个程序,则第二个程序在第一个程序写出完整缓冲区之前就不会输入它的输入。

 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 -vx="$number_of_lines" '{printf "%d\n", (NR*100/x)}' ) | zenity --progress --percentage=0 --auto-close 

我可能需要解释一下:

  1. cd / home / user需要在7z-Backup目录结构所在的文件夹中cd,否则7z将不在目录结构中。

  2. 导出number_of_files = $(找到folder_to_backup -type f | wc -l)首先计算文件压缩并导出变量供以后计算。

  3. 找到folder_to_backup -print0 -type f folder_to_backup务必是一个相对路径。 (见1)

  4. -exec sh -c“7z a -t7z /path/to/Backup.7z {} -mx9 -bd | grep压缩”\; 为每一行启动一个子shell找出并执行7z与管道grep。

  5. awk -W interactive -vx =“$ number_of_lines”'{printf'%d \ n“,(NR * 100 / x)}'提示awk为交互式(-W interactive),传播先前导出的变量(-vx = “$ number_of_lines”),最后计算并打印百分比('{printf'%d \ n“,(NR * 100 / x)')。

  6. 把所有这一切放在括号和管道到zenity。

问题不在于有节制。 这是因为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以某种方式监视压缩,例如通过在完成时将文件大小与预期的大小进行匹配并回显一个百分比。 把这个子shell放在一个正在进行压缩的子shell中。 访问http://user.cavenet.com/rolandl ,查看ftp-user.txt的例子。 Bash subshel​​l是非常方便的!