When scripting in bash or any other shell in *NIX, while running a command that will take more than a few seconds, a progress bar is needed.
For example, copying a b
I used an answer from Creating string of repeated characters in shell script for char repeating. I have two relatively small bash versions for scripts that need to display progress bar (for example, a loop that goes through many files, but not useful for big tar files or copy operations). The faster one consists of two functions, one to prepare the strings for bar display:
preparebar() {
# $1 - bar length
# $2 - bar char
barlen=$1
barspaces=$(printf "%*s" "$1")
barchars=$(printf "%*s" "$1" | tr ' ' "$2")
}
and one to display a progress bar:
progressbar() {
# $1 - number (-1 for clearing the bar)
# $2 - max number
if [ $1 -eq -1 ]; then
printf "\r $barspaces\r"
else
barch=$(($1*barlen/$2))
barsp=$((barlen-barch))
printf "\r[%.${barch}s%.${barsp}s]\r" "$barchars" "$barspaces"
fi
}
It could be used as:
preparebar 50 "#"
which means prepare strings for bar with 50 "#" characters, and after that:
progressbar 35 80
will display the number of "#" characters that corresponds to 35/80 ratio:
[##################### ]
Be aware that function displays the bar on the same line over and over until you (or some other program) prints a newline. If you put -1 as first parameter, the bar would be erased:
progressbar -1 80
The slower version is all in one function:
progressbar() {
# $1 - number
# $2 - max number
# $3 - number of '#' characters
if [ $1 -eq -1 ]; then
printf "\r %*s\r" "$3"
else
i=$(($1*$3/$2))
j=$(($3-i))
printf "\r[%*s" "$i" | tr ' ' '#'
printf "%*s]\r" "$j"
fi
}
and it can be used as (the same example as above):
progressbar 35 80 50
If you need progressbar on stderr, just add >&2
at the end of each printf command.