I want the terminal to show some kind of process bar based on time, like 1% every 60 seconds for example.
-
See How to add a progress bar to a shell script? - Stack Overflow – wjandrea Apr 23 '18 at 18:11
-
3Possible duplicate of Create a progress bar in bash – wjandrea Apr 23 '18 at 18:12
-
6To 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
-
@wjandrea I took it the question is how to create fake data that's useful in conjunction with the different progress bar solutions, so I tried to cover everything (besides custom scripts, added an own section for that) mentioned in the related question. That's just how I read the question though, please feel free to ask OP to clarify! – dessert Apr 23 '18 at 20:47
-
1Most 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
3 Answers
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 echo
s 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:
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 p
rogress 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!

- 39,982
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:
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

- 102,282
-
Why do you iterate over /usr/bin? Why not just use
for i in {1..100}
ori=100; while ((--i))
? – wjandrea Apr 24 '18 at 00:30 -
Two notes: 1) Use the newer command substitution syntax
$()
instead of backticks, which are deprecated. 2) It would be cleaner to put theyad
options in an array. – wjandrea Apr 24 '18 at 00: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. Theyad
options in an array does clean up thedone
line but I think this method illustrates to newcomers what is going on with the pipe toyad
with all the details in one spot. – WinEunuuchs2Unix Apr 24 '18 at 00: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 06:50
Taking the comment from @wjandream and just using for i in {1..100}, the third option is reduced to:
for ((i=0; i<=100; i++)); { echo "$i"; echo "# Downloading $i%";sleep 0.2; } | yad --progress --title="Downloading..." --height=90 --width=400 --center --text="Please wait..." --auto-close --no-buttons --no-escape

- 508