Emacs, scripting and anything text oriented.

Count Down Timer in Shell

Kaushal Modi

I was working on a tcsh script that did some cool stuff. But if a user ran that script not knowing the true impact of the script, it could make some bad irreversible changes.

While I could simply echo a warning statement and put a sleep 10, I wanted the wait time to be shown live.

So here’s what worked pretty nicely — The warning message is shown to the user, and the actual wait time countdown is also displayed.

#!/usr/bin/env tcsh
set wait_time = 10 # seconds

echo "Are you sure you meant to run this script?"
echo "This script does something drastic that you would severely regret if you happened to run this script by mistake!"
echo ""
set temp_cnt = ${wait_time}
# https://www.cyberciti.biz/faq/csh-shell-scripting-loop-example/
while ( ${temp_cnt} >= 1 )
    printf "\rYou have %2d second(s) remaining to hit Ctrl+C to cancel that operation!" ${temp_cnt}
    sleep 1
    @ temp_cnt--
end
echo ""

Explanation #

  • The while loop runs for $wait_time times; each time waiting for a second (sleep 1) and then decrementing the temporary counter $temp_cnt.
  • printf is chosen instead of echo -n because I wanted to have the seconds number always hold 2 character places (%2d).
  • The \r character in printf makes the magic here. It represents carriage return i.e. The cursor will return to the beginning of the line, and then print the following string, overwriting whatever there was on that line earlier.
    • printf acts like echo -n i.e. a newline is not inserted automatically at the end of the printed message. In order to add a newline at the end for printf, you need to do so explicitly by adding a \n character.

Result #

Click here to see the animation on asciinema.org.

Bash implementation #

Below is a re-implementation of the above in bash.

#!/usr/bin/env bash
wait_time=10 # seconds

echo "Are you sure you meant to run this script?"
echo "This script does something drastic that you would severely regret if you happened to run this script by mistake!"
echo ""
temp_cnt=${wait_time}
while [[ ${temp_cnt} -gt 0 ]];
do
    printf "\rYou have %2d second(s) remaining to hit Ctrl+C to cancel that operation!" ${temp_cnt}
    sleep 1
    ((temp_cnt--))
done
echo ""