用于 GNU 并行进度条的 Zenity 取消按钮

用于 GNU 并行进度条的 Zenity 取消按钮

作为GNU 并行手册显示,您可以使用并行的 zenity 进度条:

seq 1000 | parallel -j30 --bar '(echo {};sleep 0.1)' \
    2> >(zenity --progress --auto-kill) | wc

但是,在该示例中,取消按钮不起作用。我读过关于类似问题当与更常用的命令(即非并行)一起使用时使用此按钮以及关于取消按钮如何工作的更多见解但这并没有真正帮助我。并行似乎以完全不同的方式使用它,我不知道如何让取消按钮停止该过程。

我主要对2> >和感到困惑wc。如果我只是使用a |,取消按钮可以工作,但现在进度条速度更快并且完成得太早(我猜它只显示作业第一个分割部分的进度?但如果是这样的话,它应该是30次更快,但事实并非如此,所以我不确定)。

附:只是为了让您知道,我已经在并行邮件列表上讲述了这个问题。

答案1

Zenity 设计为读取两行,一行用于进度条,另一行以“#”开头表示进度文本:

for ((i=0;i<=100;i++));do
  echo "$i"                  # bar
  echo "#percent done $i"    # text
  sleep .1
done
| zenity --progress

我猜可能是- 酒吧选项将进度写入 stderr 但不关闭它或不在行尾写入换行符。这阻止了期待新线路的 Zenity。解决方法是将换行符打印到 stderr,默认情况下为文件描述符 2。

seq 1000 | parallel -j30 --bar '(echo {}; echo >&2; sleep 0.1)' \
    2> >(zenity --progress --auto-kill) | wc

答案2

所以显然zenity想要一个换行符来取消工作。

GNU Parallel 在其输出中的--bar使用\r,对于 中的进度条非常有效zenity,但令人惊讶的是对于“取消”按钮却不起作用。

因此,一种明显的解决方案是,如果您需要“取消”按钮,则在将其提供给之前替换\r为:\nzenity

seq 1000 |
  parallel -j30 --bar '(echo {}; sleep 0.1)' 2> >(perl -pe 'BEGIN{$/="\r";$|=1};s/\r/\n/g' |
    zenity --progress --auto-kill) |
  wc

一个不太明显的解决方案是使用strace和跟踪从未发生过的事情:

seq 1000 |
  parallel -j30 --bar '(echo {};sleep 0.1)' 2> >(strace -e trace=creat zenity --progress --auto-kill) |
  wc

我完全不知道为什么strace会这样。

相关内容