Skip to content

Instantly share code, notes, and snippets.

@alkemann
Last active September 6, 2025 12:12
Show Gist options
  • Select an option

  • Save alkemann/ea07dfae568b9485f1f47da53cf4c32e to your computer and use it in GitHub Desktop.

Select an option

Save alkemann/ea07dfae568b9485f1f47da53cf4c32e to your computer and use it in GitHub Desktop.
Progress bar in a bash script
#!/usr/bin/env bash
# https://ghostty.org/docs/vt/csi/el
# https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
WIDTH=100
HEIGHT=100
BATCHSIZE=5
bar() {
local iter=$1
local max=$2
local w=$max/100*2+5+5
local bar_width=$WIDTH-w
local per=$((iter * 100 / max))
local bar=$((per * bar_width / 100))
local max_padd=${#max}
local frmt="%${max_padd}d"
local pad_iter=$(printf $frmt "$iter")
local pad_per=$(printf "%3d" "$per")
local suf=" $pad_per% ($pad_iter/$max)"
local s=''
local x
for ((x=0;x<$bar;x++)) {
s+='▓'
}
for ((x=$bar;x<$bar_width;x++)) {
s+='░'
}
s+="$suf"
printf '\e7' # save cursor location
printf '\e[%d;%dH' "$LINES" 0 # move to last line
printf '\e[0K' # clear the line
printf '%s' "$s" # print content
printf '\e8' # restore cursor location
}
process_files() {
local files=("$@")
for file in "${files[@]}"; do
echo " = $file"
done
sleep 0.1
}
init-term() {
WIDTH=$COLUMNS
HEIGHT=$((LINES-1))
printf '\n' #
printf '\e7' # save cursor location
printf '\e[%d;%dr' 0 "$HEIGHT" # set scrollable region
printf '\e8' # restore cursor location
printf '\e[1A' # move cursor up
}
deinit-term() {
printf '\e7' # save cursor location
printf '\e[%d;%dr' 0 "$LINES" # reset scrollable region
printf '\e[%d;%dH' "$LINES" 0 # move to last line
printf '\e[2K' # clear the line
printf '\e8' # restore cursor location
}
main() {
shopt -s globstar nullglob checkwinsize
(:) # trigger get window size
trap deinit-term exit
trap init-term winch
init-term
local files=(./**/*cache)
local amount=${#files[@]}
local i
for ((i = 1; i <= $amount; i+=BATCHSIZE)) {
bar "$i" "$amount"
process_files "${files[@]:i:BATCHSIZE}"
}
bar "$amount" "$amount"
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment