Skip to content

Instantly share code, notes, and snippets.

@cheater
Created November 18, 2018 17:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cheater/cddf5a586f0c750502954eb7e6857058 to your computer and use it in GitHub Desktop.
Save cheater/cddf5a586f0c750502954eb7e6857058 to your computer and use it in GitHub Desktop.
sleep with countdown in bash
#!/bin/bash
sleep_time="$(( $1 - 1 ))" # subtract 1, since we wait on the 0th second.
start_s="$(date +%s)"
start_ns="$(date +%N)"
div_whole() {
# whole-number division of integers.
a="$1"
b="$2"
printf "%d" "$(( ( a - ( a % b) ) / b ))"
}
countdown() {
secs_total="$1"
hours="$( div_whole "$secs_total" 3600 )"
secs_total="$(( secs_total - ( 3600 * hours ) ))"
mins="$( div_whole "$secs_total" 60 )"
secs="$(( secs_total - 60 * mins ))"
while [ "$hours" -ge 0 ]; do # count down hours
while [ "$mins" -ge 0 ]; do # count down minutes in a single hour
while [ "$secs" -ge 0 ]; do # count down seconds in a single minute
printf "\033[0K\r%02d:%02d:%02d" "$hours" "$mins" "$secs"
secs="$((secs - 1))"
target_s="$(( sleep_time - (secs + 60 * mins + 3600 * hours) ))"
target="$(( start_s + target_s ))"
while [ "$(date +%s)" -lt "$target" ] # hi-res sleep loop
|| {
[ "$(date +%s)" -eq "$target" ]
&& [ "$(date +%N)" -lt "$start_ns" ]; };
do
sleep 0.01
done # end hi-res sleep loop
done # end count down seconds in a single minute
secs=59
mins="$((mins - 1))"
done # end count down minutes in a single hour
mins=59
hours="$((hours - 1))"
done # end count down hours
printf "\033[0K\r" # clean up after we're done
}
countdown "$sleep_time"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment