Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

How can I display a real-time countdown timer on the Linux terminal? Is there an existing app or, even better, a one liner to do this?

share|improve this question
regarding SU hold: I think this falls under "computer software" without "asking for a shopping or product recommendation". I'm not asking for recommendations; I'm asking if something even exists. When I initially asked the question, I was anticipating maybe a "yeah there is this built-in -nix script". If I can restructure the question, I will. – tir38 Jun 26 '13 at 17:40
That's what I tried to do. It is on topic after my edit as far as I am concerned and I have voted to reopen it. – terdon Jun 26 '13 at 17:41
@terdon thanks, I see how that is a better question. – tir38 Jun 28 '13 at 2:19
I can so see this on IOCCC. – Ciro Santilli 六四事件 法轮功 包卓轩 Aug 11 '15 at 13:33

13 Answers 13

up vote 64 down vote accepted

I'm not sure why you need beep, if all you want is a stopwatch, you can do this:

while true; do echo -ne "`date`\r"; done

That will show you the seconds passing in realtime and you can stop it with Ctrl+C. If you need greater precision, you can use this to give you nanoseconds:

while true; do echo -ne "`date +%H:%M:%S:%N`\r"; done

Finally, if you really, really want "stopwatch format", where everything starts at 0 and starts growing, you could do something like this:

date1=`date +%s`; while true; do 
   echo -ne "$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r";

For a countdown timer (which is not what your original question asked for) you could do this (change seconds accordingly):

seconds=20; date1=$((`date +%s` + $seconds)); 
while [ "$date1" -ge `date +%s` ]; do 
  echo -ne "$(date -u --date @$(($date1 - `date +%s` )) +%H:%M:%S)\r"; 

You can combine these into simple commands by using bash (or whichever shell you prefer) functions. In bash, add these lines to your ~/.bashrc (the sleep 0.1 will make the system wait for 1/10th of a second between each run so you don't spam your CPU):

function countdown(){
   date1=$((`date +%s` + $1)); 
   while [ "$date1" -ge `date +%s` ]; do 
     echo -ne "$(date -u --date @$(($date1 - `date +%s`)) +%H:%M:%S)\r";
     sleep 0.1
function stopwatch(){
  date1=`date +%s`; 
   while true; do 
    echo -ne "$(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r"; 
    sleep 0.1

You can then start a countdown timer of one minute by running:

countdown 60

You can countdown two hours with:

countdown $((2*60*60))

or a whole day using:

countdown $((24*60*60))

And start the stopwatch by running:


If you need to be able to deal with days as well as hours, minutes and seconds, you could do something like this:

    date1=$((`date +%s` + $1));
    while [ "$date1" -ge `date +%s` ]; do 
    ## Is this more than 24h away?
    days=$(($(($(( $date1 - $(date +%s))) * 1 ))/86400))
    echo -ne "$days day(s) and $(date -u --date @$(($date1 - `date +%s`)) +%H:%M:%S)\r"; 
    sleep 0.1
    date1=`date +%s`; 
    while true; do 
    days=$(( $(($(date +%s) - date1)) / 86400 ))
    echo -ne "$days day(s) and $(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)\r";
    sleep 0.1

Note that the stopwatch function hasn't been tested for days since I didn't really want to wait 24 hours for it. It should work but please let me know if it doesn't.

share|improve this answer
Given the thorough, well explained answer, I gotta give you the check mark! – tir38 Jun 28 '13 at 2:19
I added these nice functions to my .zshrc right after I read your answer. Today I used countdown the first time and noticed a rather high CPU usage. I added a sleep 0.1 (I don't know if a sleep time of a fractional second is supported on all systems) which improved that a lot. The drawback is of course a less accurate display accuracy, but I can live with a deviation of max. 100ms. – mpy Jul 5 '13 at 14:45
@mpy thanks for mentioning that. I am getting ~3% CPU usage when doing this in bash, I can live with that (though it is higher than I expected and I have also added the sleep to my own .bashrc). – terdon Jul 5 '13 at 14:59
Just found this answer. I found putting the carriage return at the beginning of the echo statement in the stopwatch function was handy as it meant killing the stopwatch didn't overwrite the current stopwatch time: echo -ne "\r$(date -u --date @$((date +%s - $date1)) +%H:%M:%S)"; – mkingston Jun 16 '14 at 12:51
@orip fair enough, done. – terdon Nov 19 '14 at 12:47

My favorite way is:


time cat


share|improve this answer
This is the most clever and simple. – Jikku Jose Jul 16 '15 at 4:40
+1. Lifehacker featured this trick. – Nathan Arthur Sep 9 '15 at 22:18

I've used this one:

  set -- $*
  secs=$(( ${1#0} * 3600 + ${2#0} * 60 + ${3#0} ))
  while [ $secs -gt 0 ]
    sleep 1 &
    printf "\r%02d:%02d:%02d" $((secs/3600)) $(( (secs/60)%60)) $((secs%60))
    secs=$(( $secs - 1 ))


 countdown "00:07:55"

Here's a source.

share|improve this answer
POSIX compliant - works on OS X :) – djule5 Feb 24 '15 at 1:02

I was looking for the same thing and ended up writing something more elaborate in Python:

This will give you a simple 10-second countdown:

sudo pip install termdown
termdown 10


share|improve this answer
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Doktoro Reichard Jun 6 '14 at 8:21
@DoktoroReichard: Well, this is a download link. – harrymc Jun 6 '14 at 10:42
doesn't work with python 3.x – Suhaib Jun 20 '14 at 2:18
@Suhaib: It should and does for me. Please raise an issue on GitHub with more info. – trehn Jun 27 '14 at 9:23

I ended up writing my my own shell script: github gist

# script to create timer in terminal
# Jason Atwood
# 2013/6/22

# start up
echo "starting timer script ..."
sleep 1 # seconds

# get input from user
read -p "Timer for how many minutes?" -e DURATION
DURATION=$(( $DURATION*60 )) # convert minutes to seconds

# get start time
START=$(date +%s)

# infinite loop
while [ -1 ]; do
clear # clear window

# do math
NOW=$(date +%s) # get time now in seconds
DIF=$(( $NOW-$START ))  # compute diff in seconds
ELAPSE=$(( $DURATION-$DIF ))    # compute elapsed time in seconds
MINS=$(( $ELAPSE/60 ))  # convert to minutes... (dumps remainder from division)
SECS=$(( $ELAPSE - ($MINS*60) )) # ... and seconds

# conditional
if [ $MINS == 0 ] && [ $SECS == 0 ] # if mins = 0 and secs = 0 (i.e. if time expired)
then # blink screen
for i in `seq 1 180`; # for i = 1:180 (i.e. 180 seconds)
clear # flash on
setterm -term linux -back red -fore white # use setterm to change background color
echo "00:00 " # extra tabs for visibiltiy

sleep 0.5

clear # flash off
setterm -term linux -default # clear setterm changes from above
echo "00:00" # (i.e. go back to white text on black background)
sleep 0.5
done # end for loop
break   # end script

else # else, time is not expired
echo "$MINS:$SECS"  # display time
sleep 1 # sleep 1 second
fi  # end if
done    # end while loop 
share|improve this answer
Nice script, +1. Just so you know, that is a countdown timer, not a stopwatch. – terdon Jun 25 '13 at 12:17
ha you're right, thats what I really wanted. I'll update my naming. – tir38 Jun 26 '13 at 17:31

This is for a stopwatch with hundredths of second

#!/usr/bin/awk -f
func z() {
  getline < y
  return $0
  y = "/proc/uptime"
  x = z()
  while (1)
    printf "%s\r", z() - x


share|improve this answer

I have combined the very good terdon's answer, into function which at the same time displays time since start, and time till end. There are also three variants so it's easier to call (you don't have to do bash math), and it's also abstracted. Example of use:

{ ~ }  » time_minutes 15
Counting to 15 minutes
Start at 11:55:34     Will finish at 12:10:34
     Since start: 00:00:08     Till end:  00:14:51

And something like work timer:

{ ~ }  » time_hours 8
Counting to 8 hours
Start at 11:59:35   Will finish at 19:59:35
     Since start: 00:32:41     Till end:  07:27:19

And if you need some very specific time:

{ ~ }  » time_flexible 3:23:00
Counting to 3:23:00 hours
Start at 12:35:11   Will finish at 15:58:11
     Since start: 00:00:14     Till end:  03:22:46

Here's the code to put into your .bashrc

function time_func()
   date2=$((`date +%s` + $1));
   date1=`date +%s`;
   date_finish="$(date --date @$(($date2)) +%T )"

   echo "Start at `date +%T`   Will finish at $date_finish"

    while [ "$date2" -ne `date +%s` ]; do
     echo -ne "     Since start: $(date -u --date @$((`date +%s` - $date1)) +%H:%M:%S)     Till end:  $(date -u --date @$(($date2 - `date +%s`)) +%H:%M:%S)\r";
     sleep 1

    printf "\nTimer finished!\n"
    play_sound ~/finished.wav

function time_seconds()
  echo "Counting to $1 seconds"
  time_func $1

function time_minutes()
  echo "Counting to $1 minutes"
  time_func $1*60

function time_hours()
  echo "Counting to $1 hours"
  time_func $1*60*60

function time_flexible()  # accepts flexible input hh:mm:ss
    echo "Counting to $1"
    secs=$(time2seconds $1)
    time_func $secs

function play_sound()  # adjust to your system
    cat $1 > /dev/dsp

function time2seconds() # changes hh:mm:ss to seconds, found on some other stack answer
    a=( ${1//:/ }) 
    echo $((${a[0]}*3600+${a[1]}*60+${a[2]})) 

Combine this with some way of playing sound in linux terminal (play mp3 or wav file via Linux command line) or cygwin (cat /path/foo.wav > /dev/dsp works for me in babun/win7) and you have a simple flexible timer with alarm!

share|improve this answer

Another approach

countdown=60 now=$(date +%s) watch -tpn1 echo '$((now-$(date +%s)+countdown))'

For Mac:

countdown=60 now=$(date +%s) watch -tn1 echo '$((now-$(date +%s)+countdown))'
#no p option on mac for watch

If one wants a signal when it hits zero, one could e.g. build it with a command that returned a non-zero exit status at zero and combine it with watch -b, or something, but if one wants to build a more elaborate script, this is probably not the way to go; it is more of a "quick and dirty one-liner" type solution.

I like the watch program in general. I first saw it after I had already written countless while sleep 5; do loops to different effects. watch was demonstrably nicer.

share|improve this answer

Pretend you are a person on OSX looking for a command line stopwatch. Pretend that you don't want to install the gnu tools and just want to run with the unix date

in that case do as @terdon says but with this modification:

function stopwatch(){
    date1=`date +%s`; 
    while true; do 
        echo -ne "$(date -jf "%s" $((`date +%s` - $date1)) +%H:%M:%S)\r"; 
        sleep 0.1
share|improve this answer
I tried it on OS X El Capitan, for some reason it is starting with 16:00:00 – 太極者無極而生 Oct 29 '15 at 2:34

def stopwatch ( atom = .01 ):
    import time, sys, math

    start = time.time()
    last = start
    sleep = atom/2
    fmt = "\r%%.%sfs" % (int(abs(round(math.log(atom,10))))  if atom<1 else "")
    while True:
        curr = time.time()
        subatom = (curr-last)
        if subatom>atom:
            # sys.stdout.write( "\r%.2fs" % (curr-start))
            sys.stdout.write( fmt % (curr-start))
            last = curr

share|improve this answer

For future reference, there is a command line tool called µTimer with very straightforward command line options for a countdown/count-up timer.

share|improve this answer

Simply use watch + date in UTC time. You can also install some package for big display...

export now="`date +%s -u`";
watch -n 0,1 'date +%T -u -d @$((`date +%s` - $now ))'

#Big plain characters
watch -n 0,1 'date +%T -u -d @$((`date +%s` - $now )) | toilet -f mono12'

#Big empty charaters
watch -n 0,1 'date +%T -u -d @$((`date +%s` - $now )) | figlet -c -f big'

Try it!

See also

share|improve this answer

If you would like a compile-able program for whatever reason, the following would work:

#include <iostream>
#include <string>
#include <chrono>

int timer(seconds count) {
  auto t1 = high_resolution_clock::now();
  auto t2 = t1+count;
  while ( t2 > high_resolution_clock::now()) {
    std::cout << "Seconds Left:" <<
    std::endl <<
      duration_cast<duration<double>>(count-(high_resolution_clock::now()-t1)).count() << 
    std::endl << "\033[2A\033[K";
  std::cout << "Finished" << std::endl;
  return 0;

This can be used in other programs as well and easily ported, if a bash environment isn't available or you just prefer using a compiled program


share|improve this answer
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Ƭᴇcʜιᴇ007 Aug 18 '14 at 18:06
Thanks for the input! – elder4222 Aug 18 '14 at 22:19

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.