Created
September 5, 2025 02:26
-
-
Save emmaly/3fb4a925729f3297fb8ec3c5008c353c to your computer and use it in GitHub Desktop.
countdown_with_spinner
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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