Skip to content

Instantly share code, notes, and snippets.

@emmaly
Created September 5, 2025 02:26
Show Gist options
  • Save emmaly/3fb4a925729f3297fb8ec3c5008c353c to your computer and use it in GitHub Desktop.
Save emmaly/3fb4a925729f3297fb8ec3c5008c353c to your computer and use it in GitHub Desktop.
countdown_with_spinner
#!/usr/bin/env bash
# countdown_with_spinner
# Arguments:
# $1: Duration to wait in seconds
# $2: Animation interval in seconds (e.g., 0.1)
# $3: Spinner characters (string)
# $4: Custom format string (optional) - use %s for spinner, %d for time, %s for unit
# Default: "%s Waiting %d %s..."
countdown_with_spinner() {
local duration="${1:-10}"
local interval="${2:-0.1}"
local spinner="${3:-⣾⣽⣻⢿⡿⣟⣯⣷}"
local format="${4:-%s Waiting %d %s...}"
local spinner_len=${#spinner}
local start_time=$(date +%s.%N)
local end_time=$(bc <<< "$start_time + $duration")
local spinner_counter=0
local last_spinner_update=$start_time
while true; do
local current_time=$(date +%s.%N)
local time_left=$(bc <<< "scale=2; $end_time - $current_time")
# Exit if countdown complete
if (( $(echo "$time_left <= 0" | bc -l) )); then
break
fi
# Update spinner if interval has passed
local time_since_spinner=$(bc <<< "scale=2; $current_time - $last_spinner_update")
if (( $(echo "$time_since_spinner >= $interval" | bc -l) )); then
spinner_counter=$(( (spinner_counter + 1) % spinner_len ))
last_spinner_update=$current_time
fi
local spinner_char=${spinner:spinner_counter:1}
# Always round up (ceiling), with minimum of 1
local display_time=$(bc <<< "scale=0; if ($time_left > 0) { ($time_left + 0.999) / 1 } else { 1 }")
# Ensure minimum of 1
if [ "$display_time" -eq 0 ]; then
display_time=1
fi
local unit="seconds"
if [ "$display_time" -eq 1 ]; then
unit="second"
fi
# Format and print the countdown
printf "\r$(printf "$format" "$spinner_char" "$display_time" "$unit") "
# Sleep for a short time to update display smoothly
sleep 0.05
done
# Clear the line
printf "\r%*s\r" 50 ""
}
# Export the function for use in other scripts
export -f countdown_with_spinner
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment