Skip to content

Instantly share code, notes, and snippets.

@LukeSavefrogs
Forked from F1LT3R/progress-bar.sh
Last active January 2, 2022 02:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LukeSavefrogs/639c7a70f69f677f4969ce3c32fc9c91 to your computer and use it in GitHub Desktop.
Save LukeSavefrogs/639c7a70f69f677f4969ce3c32fc9c91 to your computer and use it in GitHub Desktop.
Bash Progress Bar
#!/bin/bash
# Bash Progress Bar: https://gist.github.com/F1LT3R/fa7f102b08a514f2c535
# Function to draw progress bar
progressBar () {
local __message="";
local -i __current=0 __total=100;
local -i __progress_bar_width=50;
local -i __highlight_items=0 __highlighted=0;
local -i __percentage=0;
local -i __fill=0 empty=0;
local fill_char="=" empty_char=" " highlight_char="=";
local fill_color="\033[1m" empty_color="\033[0m" highlight_color="\033[1;90m" reset_color="\033[0m";
OPTIND=1;
POSITIONAL=();
while [[ $# -gt 0 ]]; do
case $1 in
-c | --current)
__current="$2";
shift 2;
;;
--highlight)
__highlight_items="$2";
shift 2;
;;
-t | --total)
__total="$2";
shift 2;
;;
-w | --width)
__progress_bar_width="$2";
shift 2;
;;
-m | --message)
__message="$2";
shift 2;
;;
-\? | -h |--help)
# Call to usage function goes here
return 0;
;;
-*)
echo "Unknown option: $1" >&2;
return 1;
;;
*)
POSITIONAL+=("$1");
shift;
;;
esac;
done;
[[ ${#POSITIONAL[@]} -gt 0 ]] && set -- "${POSITIONAL[@]}";
[[ -z "${__current}" ]] && { __current=$1; shift; };
[[ -z "${__total}" ]] && { __total=$1; shift; };
__progress_bar_width=$((__progress_bar_width - 8 - 2 - 1)); # 8=percentage, 2=[] and 1=space
if [[ -n "${__message:-}" ]]; then
# __progress_bar_width=$((__progress_bar_width - 3 - ${#__message})); # 3 for the separator (" - ")
__progress_bar_width=$(awk 'BEGIN {print int(('"${__progress_bar_width}"' / 1.5))}');
fi;
# Calculate number of fill/empty slots in the bar
__fill=$((__current * __progress_bar_width / __total));
if ((__fill > __progress_bar_width)); then
__fill=${__progress_bar_width};
fi
empty=$((__progress_bar_width - __fill));
if ((__highlight_items > 0 && __highlight_items <= __current)); then
__highlighted=$((__highlight_items * __progress_bar_width / __total));
if ((__highlighted > __progress_bar_width)); then
__highlighted=0;
fi
__fill=$((__fill - __highlighted));
empty=$((__progress_bar_width - __fill - __highlighted));
fi
# Percentage Calculation
__percentage=$(((__current - __highlight_items) * 100 / __total));
if (( __percentage > 100 )); then
__percentage="100.00";
fi
# Output to screen
screen="$(
printf "\33[2K\r[";
(( __fill > 0 )) && printf "${fill_color}%*s${reset_color}" "${__fill}" " " | tr " " "${fill_char}" | sed "s/\(.*\)${fill_char}/\1>/g";
if ((__highlighted > 0)); then
printf "${highlight_color}%*s${reset_color}" "${__highlighted}" " " | tr " " "${highlight_char}" | sed "s/\(.*\)${highlight_char}/\1>/g";
fi
(( empty > 0 )) && printf "${empty_color}%*s${reset_color}" "${empty}" " " | tr " " "${empty_char}";
printf "] %6.2f%%" "${__percentage}";
if [[ -n "${__message}" ]]; then
printf -- " - %s" "${__message}";
fi;
)";
printf "%s" "${screen}"
}
for ((index=1; index <= 10; index++)); do
# Intermediate step (for example, data fetching)
progressBar --highlight 1 --current "${index}" --total 10 --width "$(tput cols)" --message "Progress: ${index} of 10";
sleep 1
# Step finished, update progress bar
progressBar --current "${index}" --total 10 --width "$(tput cols)" --message "Progress: ${index} of 10";
sleep 1
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment