Skip to content

Instantly share code, notes, and snippets.

@thcipriani
Last active December 22, 2021 23:40
Show Gist options
  • Select an option

  • Save thcipriani/a34545cc8e3bf0284bc0bc9b8f8487dd to your computer and use it in GitHub Desktop.

Select an option

Save thcipriani/a34545cc8e3bf0284bc0bc9b8f8487dd to your computer and use it in GitHub Desktop.
A simple(ish) progress bar in bash
#!/usr/bin/env bash
# Fancy progress bar, in bash!
TOTAL=100
DELAY=0.1
PROGRESS=
get_progress() {
local perc dperc item total scale cols lines output
cols=$(tput cols)
item=$1
shift
total=$1
perc="$(printf "%d/%d\n" "$item" "$total" | bc --mathlib | tr -d '\\\n')"
dperc="$(printf "%f*100\n" "$perc" | bc --mathlib | tr -d '\\\n')"
dperc="$(printf "%0.2f" "$dperc")"
PROGRESS=$(printf "Progress %s%% (%d/%d)" "$dperc" "$item" "$total")
cols="$(printf "%d-%d\n" "$cols" "${#PROGRESS}" | bc | tr -d '\\\n')"
width="$(printf "%d*%0.2f\n" "$cols" "$perc" | bc --mathlib | tr -d '\\\n')"
width="$(printf "%0.0f" "$width")"
output=
while (( ${#output} < width )); do
output="${output}#"
done
PROGRESS=$(printf "\033[42m%s\033[49m%s" "$PROGRESS" "$output")
}
update_progress() {
local lines first_scrollable_line last_scrollable_line progress
progress=$1
lines=$(tput lines)
first_scrollable_line=0
last_scrollable_line=$(( lines - 1 ))
# Scoot off the baseline, if we're there
printf '\n'
# Save our current cursor
# (tput sc)
printf '\033[s'
# Make a scroll region that excludes the last line
# ([using tput you don't have to subtract 1] tput csr $(tput lines) 0)
printf '\033[%d;%dr' "$first_scrollable_line" "$last_scrollable_line"
get_progress "$i" "$TOTAL"
# Move cursor to last line, write stuff
# (tput cup $(tput lines) 0)
printf "\033[%d;0f\033[K%s" "$lines" "$PROGRESS"
# Restore our cursor
# (tput rc)
printf '\033[u\033[1A'
}
cleanup() {
local lines
lines=$(tput lines)
# Save our current cursor
# (tput sc)
printf '\033[s'
# Clear the last line
# (tput cup $(tput lines) 0; tput clear)
printf "\033[%d;0f\033[K" "$lines"
# Reset scroll region
printf '\033[0;%dr' "$(tput lines)"
# Restore our cursor
# (tput rc)
printf '\033[u\033[J'
}
main() {
i=0
while (( i < TOTAL )); do
update_progress "$i" "$TOTAL"
echo "$i -- This. Is Progress"
sleep "$DELAY"
(( i++ ))
done
}
trap cleanup EXIT
main "$@"
@thcipriani

thcipriani commented Dec 15, 2016

Copy link
Copy Markdown
Author

progress

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment