【问题标题】:How to send values to Zenity progress bar如何将值发送到 Zenity 进度条
【发布时间】:2012-12-09 07:28:27
【问题描述】:

我编写了一个使用 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 没有问题。也许问题出在你在里面的管道上。
  • @Untitled 你是对的,我忘了补充,我现在已经更新了我的问题:)
  • 您对 zenity 的输入是什么?什么运行 /home/user/Desktop/Backup.7z /home/user/Desktop/folder_to_backup -mx9 | fgrep 压缩 |荷兰 | awk '{print $1}' 给你?
  • @Untitled 输入是 awk 的输出,它是一系列递增的整数(1,2,3...,取决于要压缩的文件数量)。如果我运行该代码(我刚刚意识到有一个小错误,我忘了在其中添加7z a -t7z),我会在新的一行中得到1 2 3
  • [unix] meter progress。祝你好运。

标签: linux shell progress-bar zenity


【解决方案1】:

看起来您没有在输出中获得命令的进度,请通过运行不带 | 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 &) 生成另一个子shell,它将在后台启动COMMAND2
  4. while :; 开始无限循环。
  5. tail FILE 读取FILE的最后10行。
  6. grep -o 仅打印匹配行的匹配(非空)部分。
  7. [0-9]*% 后跟 % 符号的任意数字序列。
  8. tail -1 读取上一个管道命令的最后一行。

【讨论】:

    【解决方案2】:

    无需创建临时文件的解决方案

    在头痛和流鼻血之后我终于得到了它......

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

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

    我可能需要解释一下:

    1. cd /home/user 您需要 cd 到您希望 7z-Backup 中的目录结构所在的文件夹中,否则 7z 不会在存档中放置目录结构。 p>

    2. export number_of_files=$(find folder_to_backup -type f | wc -l)首先计算要压缩的文件,然后导出变量以供以后计算。

    3. find folder_to_backup -print0 -type f folder_to_backup 必须是相对路径。 (见 1.)

    4. -exec sh -c "7z a -t7z /path/to/Backup.7z {} -mx9 -bd | grep Compressing" \; 为查找的每一行启动一个子shell用管道输出并执行 7z 到 grep。

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

    6. 将所有这些放在括号中,然后用管道连接到 zenity。

    【讨论】:

    • 也感谢您的回答:)
    【解决方案3】:

    问题不在于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
    

    【讨论】:

    • 这就是为什么我想使用 grep 来生成一些输出并将其通过管道传送到 zenity,我虽然这可以工作......
    • 我的想法是自己用这样的东西来计算百分比:awk '{print $1/$number_of_files*100}'
    • 你打算用 1 美元买什么?您需要当前的文件数量,但 7z 的标准输出中没有。
    • 出现“压缩”一词的次数,因为 grep 按预期工作。
    • 并且可以计算出当前的文件数量,所以我掌握了所有这些信息。我只是不明白为什么zenity看不到他们
    【解决方案4】:

    您将需要一个带有代码的子shell,以某种方式监控压缩,例如通过在完成时将文件大小与预期大小进行匹配,并回显一个百分比。将该子壳放在进行压缩的子壳内。访问http://user.cavenet.com/rolandl 并查看 ftp-user.txt 以获取示例。 Bash 子shell 非常方便!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-21
      • 1970-01-01
      • 1970-01-01
      • 2019-03-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      相关资源
      最近更新 更多