I would like to have a count down of 5 minutes, updating every second and showing the result on the same line. Is this even possible with Bash scripting?
Asked
Active
Viewed 5.2k times
29
-
What does the countdown do? You need to be a little more specific about the whole thing. – Adrian Frühwirth Aug 21 '13 at 09:41
-
This is absolutely possible. If you tell us why (what actual system/network administration problem you're trying to solve) we can tell you which of the many available methods to do it will likely work best for you. If it's a general "How do I do this in a `bash` script?` question your question is probably better suited to [unix.se] -- let me know and I can migrate it there for you :) – voretaq7 Aug 21 '13 at 14:04
-
Here's a way https://github.com/himanshub16/MyScripts/blob/master/countdown.sh – Himanshu Shekhar Jun 01 '16 at 19:13
2 Answers
59
This works from Bash shell:
secs=$((5 * 60))
while [ $secs -gt 0 ]; do
echo -ne "$secs\033[0K\r"
sleep 1
: $((secs--))
done
The special character \033[0K represents an end of line which cleans the rest of line if there are any characters left from previous output and \r is a carriage return which moves the cursor to the beginning of the line. There is a nice thread about this feature at stackoverflow.com.
You can add own commands or whatever in the while loop. If you need something more specific please provide me more details.

Software Engineer
- 103
- 4

dsmsk80
- 5,817
- 18
- 22
-
Do you mean \033[K as per http://ascii-table.com/ansi-escape-sequences.php instead of 0K? – Jody Bruchon Oct 04 '15 at 00:04
-
I put `\r` at the beginning to put cursor at the end of line (which prevent it to hide the first character). Here is the updated version: https://gist.github.com/boillodmanuel/676b3af823fae4177f1d0b41a6f23442 Thanks – user1067920 Nov 08 '19 at 10:11
-
1Note for anyone confused by the leading colon on line 5: That is the null operator, allowing the following `$((...))` construction to be evaluated without being interpreted as a command. However, I believe the same effect can be had more simply by just putting `((secs--))` in place of `: $((secs--))`. – shawkinaw Jan 13 '20 at 15:33
-
15
Here's one with an improvement of right output format (HH:MM:SS) with proper leading zeros and supporting hours:
#!/bin/bash
m=${1}-1 # add minus 1
Floor () {
DIVIDEND=${1}
DIVISOR=${2}
RESULT=$(( ( ${DIVIDEND} - ( ${DIVIDEND} % ${DIVISOR}) )/${DIVISOR} ))
echo ${RESULT}
}
Timecount(){
s=${1}
HOUR=$( Floor ${s} 60/60 )
s=$((${s}-(60*60*${HOUR})))
MIN=$( Floor ${s} 60 )
SEC=$((${s}-60*${MIN}))
while [ $HOUR -ge 0 ]; do
while [ $MIN -ge 0 ]; do
while [ $SEC -ge 0 ]; do
printf "%02d:%02d:%02d\033[0K\r" $HOUR $MIN $SEC
SEC=$((SEC-1))
sleep 1
done
SEC=59
MIN=$((MIN-1))
done
MIN=59
HOUR=$((HOUR-1))
done
}
Timecount $m
Gives an output that looks like this:
02:04:15

user1855221
- 103
- 2

rahuL
- 692
- 3
- 12
- 31
-
The output isn't quite `HH:MM:SS`. For single digit minutes or seconds, you could see `00:4:5`. – chishaku Oct 14 '15 at 14:58