When I want to graphically show a process is some percent complete on the command line, I use a simple Zsh script.
Usage
completion_bar.shUsage: completion_bar.sh <width> <numerator> <denominator> [ <charset> ]
I just decide how many characters wide I want the graphic to be and give it the numerator and denominator of the percent completion I want to depict. Here are a few examples:
10 characters, 13/45=29% completion
completion_bar.sh 10 13 45##*-------
50 custom characters
completion_bar.sh 50 25 30 "|>:."|||||||||||||||||||||||||||||||||||||||||>........
Block characters
completion_bar.sh 10 13 30 "█▓▒░"████▒░░░░░
UTF-8 characters
completion_bar.sh 10 7 20 "⌾⨀◯◦"⌾⌾⌾⨀◦◦◦◦◦◦
The script doesn’t use anything but ZSH to produce the output.
completion_bar.sh
#!/usr/bin/env zsh
if [[ -z ${1} ]] || [[ -z ${2} ]] || [[ -z ${3} ]]; then
echo "Usage: $(basename $0) <width> <numerator> <denominator> [ <charset> ]"
exit 1
fi
width="${1}"
numerator="${2}"
denominator="${3}"
charset="${4:="#*=-"}"
bar=""
if [[ "$denominator" -eq "0" ]]; then
bar_segments_full="0"
else
# float representing bar segments complete relative to width, e.g., 11.6 of width 12
bar_segments_float="$(printf "%.1f\n" "$(( ${numerator}.0 * ${width}.0 / ${denominator}.0 ))" )"
# bar segments tenths as a decimal, e.g., 6 for 11.6
bar_segments_tenths_remainder="$(echo $bar_segments_float | sed -E 's/[0-9]+\.//')"
# floor of bar segments, e.g., 11 for 11.6
bar_segments_full="$(printf "%.d\n" $bar_segments_float)"
fi
# render the characters depicting fully complete
for ((i=1; i<=$((${bar_segments_full})); i++)); do
bar+="${charset:0:1}"
done
# render the characters depicting partially complete
if [[ "$(( $bar_segments_full + 1 ))" -le "$width" ]] && [[ "$bar_segments_tenths_remainder" -ne "0" ]]; then
if [[ "$bar_segments_tenths_remainder" -ge "5" ]]; then
bar+="${charset:1:1}"
else
bar+="${charset:2:1}"
fi
fi
# render the characters depicting not yet complete
bar_segments_empty=$((${width} - ${#bar}))
for ((i=1; i<=${bar_segments_empty}; i++)); do
bar+="${charset:3:1}"
done
echo "$bar"