3

As GNU parallel's manual shows, you can use a zenity progress bar with parallel:

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

However, in that example, the cancel button doesn't work. I've read about similar issues with this button when used with more usual commands (i.e. not parallel) as well as some more insight about how that cancel button works but that didn't really help me. Parallel seems to make use of it quite differently and I can't figure out how to get that cancel button to stop the process.

I'm mostly confused by the 2> > and the wc. If I just use a | instead, the cancel button works but now the progress bar goes faster and finishes too early (I guess it only shows the progress of the first split part of the job? But if that was the case it should be 30 times faster, which it's not, so I'm not sure).

PS: Just to let you know, I've told about this issue on the parallel mailing list.

2
  • Sure. I updated the question and added some more info. Thanks for trying to help. Jul 20, 2020 at 20:14
  • 1
    I think seq 1000|parallel -j3 --bar '(echo {};sleep 0.1)' 2>&1 1>/dev/null|zenity --progress is basically the same as the original command (without the wc), but Cancel does not work. On the other hand, removing 1>/dev/null (thus redirecting both stderr and stdin to zenity) results in Cancel working. I must be missing something, maybe someone can catch on this hint and be able to write an answer.
    – Quasímodo
    Jul 20, 2020 at 21:38

2 Answers 2

3
+50

Zenity is desinged to read two lines, one for progress bar and one begining with "#" for progress text:

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

I guess that --bar option writes progress to stderr but doesn't close it or doesn't write a newline character at the end of the line. That blocks zenity which expects a new line. The workaround is to print newline to stderr which is file descriptor 2 by default.

seq 1000 | parallel -j30 --bar '(echo {}; echo >&2; sleep 0.1)' \
    2> >(zenity --progress --auto-kill) | wc
4
  • Thank you! Do you think this could be added to the manual? Jul 21, 2020 at 7:29
  • ok wait... What does >&2 do exactly? Jul 21, 2020 at 9:25
  • >&2 is redirecting stdout to file descriptor "2" meaning stderr. All normal output from the command will be sent to stderr. gnu.org Redirections Jul 21, 2020 at 10:36
  • Either added to the manual or developers could fix it since the manual claims it is compatible with zenity. On the other hand, it could be a bug with zenity. Same thing happens with yad (yet another dialog) progress bar, and yad is a fork of zenity. Jul 21, 2020 at 10:50
1

So apparently zenity wants a newline for Cancel to work.

GNU Parallel's --bar uses \r in its output, which works great for the progress bar in zenity, but surprisingly not for the Cancel button.

One obvious solution is therefore to replace \r with \n before feeding it to zenity if you need the Cancel button:

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

A less obvious solution is to use strace and trace for something that never happens:

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

I have absolutely no idea why strace makes this work.

7
  • hehe ok, so it seems I found a weird one. Thanks for helping. On my side, your first bit of code makes a progress bar that stays at 0 until it hits 100% but anyway, I have 2 working solutions couting Miloš Pavlović's so that's fine. Jul 21, 2020 at 18:11
  • 1
    @ChameleonScales Sorry. A random : somehow sneaked in. Fixed.
    – Ole Tange
    Jul 21, 2020 at 19:57
  • cool. So now I'm wondering, do you think there's a benefit to using one of your commands instead of Miloš Pavlović's? So far they all seem to work the same for me but I don't know if one of them is a better/safer solution. Jul 24, 2020 at 7:15
  • 1
    There is not really a huge difference. I have found a small difference: If you use --files my solutions will work, whereas Miloš' solution will not. Otherwise I will consider it a matter of taste.
    – Ole Tange
    Jul 24, 2020 at 16:51
  • The first one will not continue after clicking on OK. seq 100 | parallel -j30 --bar '(echo {}; sleep 0.1)' 2> >(perl -pe 'BEGIN{$/="\r";$|=1};s/\r/\n/g' | zenity --progress --auto-kill && zenity --about) | wc Works with strace. Strace probably does line buffering. Jul 27, 2020 at 20:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.