Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

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

14 Answers 14

up vote 81 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
similar, but you can press Enter to stop it: time read – wjandrea May 25 at 1:07

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 love it - this is right up my alley – Wayne Werner Feb 10 at 16:08

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

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

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

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

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

This is similar to the accepted answer, but terdon's countdown()gave me syntax errors. This one works great for me, though:

function timer() { case "$1" in -s) shift;; *) set $(($1 * 60));; esac; local S=" "; for i in $(seq "$1" -1 1); do echo -ne "$S\r $i\r"; sleep 1; done; echo -e "$S\rTime's up!"; }

You can put it in .bashrc and then execute with: timer t (where t is time in minutes).

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

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .