How to send values to Zenity progress bar

user1301428 picture user1301428 · Dec 21, 2012 · Viewed 8.3k times · Source

I've written a simple script that uses 7zip to backup a directory. Everything works, but now I wanted to add some graphical feedback to it, adding a progress bar. I know that I can do this with zenity but, no matter what I try, I can't seem to make it work.

I am using fgrep to find out when a new file is being compressed ("Compressing" is the first word of every line printed on screen by 7zip) in order to make the bar increase. The specific line of code is the following:

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

Running this makes the progress bar appear, starting from 0, but no progress is shown: when the operation is complete, the bar suddenly jump to the end.

I've googled this for a while but the only thing I've found out is that zenity progress seems to have some problems :D Any help would be highly appreciated!

Answer

user1006989 picture user1006989 · Dec 21, 2012

Looks like you are not getting the progress of the command in your output, check it out by running your command without the | zenity --progress --percentage=0 --auto-close pipe.

Try something like this to get your output, first you need to apt-get install screen if you don't have it installed:

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"'

I'll break down the most important parts of the command:

  1. screen -L This flag tells the screen command to start a new session and log all terminal output to a file, ~/screenlog.0 by default.
  2. bash -c COMMAND1 Spawn a subshell and run COMMAND1 in it.
  3. (COMMAND2 &) Spawn another subshell that will launch COMMAND2 in the background.
  4. while :; Start an infinite loop.
  5. tail FILE Read last 10 lines of FILE.
  6. grep -o Print only the matched (non-empty) parts of a matching line.
  7. [0-9]*% Any series of digits followed by the % symbol.
  8. tail -1 Read last line of previous piped command.