4

I want the terminal to show some kind of process bar based on time, like 1% every 60 seconds for example.

  • 3
    Possible duplicate of Create a progress bar in bash – wjandrea Apr 23 '18 at 18:12
  • 6
    To reviewers: IMO this is neither unclear nor a duplicate to the linked question, it asks precisely for a fake progress bar and is quite clear about the fake data. If you consider this unclear nevertheless, please add a comment explaining how OP can improve the question. – dessert Apr 23 '18 at 18:49
  • 1
    @dessert Re my dupe flag, I don't see how a fake progress bar is different from a real one. Edit: after reading your answer, I think I get it, but I could still use some clarity. – wjandrea Apr 23 '18 at 20:20
  • 1
    Most of the progress bar examples I've seen online are fake in the first place so people can copy and paste them :) – WinEunuuchs2Unix Apr 23 '18 at 21:44
7

Create a progress bar in bash lists approaches to get a progress bar, so I'll concentrate on the How to fake part here. I'll use 2 seconds instead of your 60 here just for testing, adjust the sleep value to your exact needs.

Using dialog, whiptail or zenity (GUI)

for i in {1..100}; do sleep 2; echo $i; done | dialog --gauge 'Running...' 6 60 0

This for loop loops1 over the numbers one to hundred and echos them every 2 seconds, the output is then piped to dialog, which shows the number as the progress on a progress bar. This approach works for whiptail and zenity --progress (GUI) as well. dialog's output looks like this with a colored progress bar using 'curses' in text mode:

dialog progress bar

Using pv

for i in {1..100}; do sleep 2; echo; done | pv -pWs100 >/dev/null

This loop is very similar, just that it prints only a newline (=1 byte of data) every 2 seconds, pv is then told to expect exactly 100 bytes of data and show a progress bar. In a terminal window with a width of 80 characters the output looks like this:

[===============>                                                          ] 22%

Constructing your own progress bar

With a simple loop you can also construct your own progress bar. Here are some examples that just print 100 # in one line, one per 2 seconds:

# number signs only
$ for i in {1..100}; do sleep 2; echo -n \#; done; echo
####################################################################################################

# with progress in % on the right
$ for i in {1..100}; do sleep 2; printf "%0.s#" $(seq 1 $i); printf "%0.s " $(seq $i 100); printf "%3d%%\r" "$i"; done; echo
######################################################                                                54%

# with progress in % on the left
$ for i in {1..100}; do sleep 2; printf "%3d%% " "$i"; printf "%0.s#" $(seq 1 $i); printf "%0.s " $(seq $i 100); printf "\r"; done; echo
 39% ####################################### 

1 Look, a Polyptoton!

| improve this answer | |
3

Fake Progress Bar

This progress bar uses real data in /bin directory which everyone has. The script can be "dumbed down" to suit your fake needs. Or it can be expanded for a real life application:

yad-progress-bar.gif

It uses yad which is a super-charged version of zenity the default GUI used in the terminal. To install yad use:

sudo apt install yad

Here's the code:

#!/bin/bash

# NAME: yad-progress-bar
# PATH: /mnt/e/bin
# DESC: Display yad progress bar % with names.
# DATE: Apr 23, 2018.  Modified Oct 18, 2019.

Source="/bin"
Title="Processing files for: $Source"
Count=0  
AllFiles=$(ls $Source/* | wc -l)

for f in "$Source"/* ; do

    echo "#$f"              # Display file name in progress bar.
    Count=$(( $Count + 1 ))
    Percent=$(( Count * 100 / AllFiles ))
    echo $Percent           # Display percent complete in progress bar.
    sleep .025

done | yad --progress       --auto-close \
    --width=500             --height=300 \
    --title="$Title"        --enable-log "Current filename" \
    --log-expanded          --log-height=250 \
    --log-on-top            --percentage=0 \
    --no-cancel             --center
| improve this answer | |
  • Why do you iterate over /usr/bin? Why not just use for i in {1..100} or i=100; while ((--i)) ? – wjandrea Apr 24 '18 at 0:30
  • Two notes: 1) Use the newer command substitution syntax $() instead of backticks, which are deprecated. 2) It would be cleaner to put the yad options in an array. – wjandrea Apr 24 '18 at 0:34
  • 1
    @wjandrea I looped through /usr/bin to give some text to the progress display. I know backticks are frowned upon these days but it was old code I had laying around which I copied without doing a lot of work. I've removed them. The yad options in an array does clean up the done line but I think this method illustrates to newcomers what is going on with the pipe to yad with all the details in one spot. – WinEunuuchs2Unix Apr 24 '18 at 0:42
  • +1 for… a nice answer. ;D OP asked for the terminal to show some kind of process bar, which is why I concentrated on non-GUI solutions, but this is not at all detrimental to the usefulness of your approach. Thanks for sharing the knowledge! – dessert Apr 24 '18 at 6:50

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.