I'm looking for an app to organize my daily tasks in different countdown timers similar to the one found at www.timeanddate.com/timer/

Features I'm looking for would be:

  • runs in terminal bash or zsh
  • multiple independent countdown timers
  • plays a sound or notification display once a timer runs out

Please note that timetracking is not an important feature, just the countdown is enough.

Thank you.

enter image description here

  • 1
    I know Emacs' org-mode has a countdown-timer feature, but I've never used it and know nothing else about it. It might be something look into, though. – Nick Weinberg Sep 25 '16 at 2:12
  • Of the top of my head I could think of a python script that does timer countdown , perhaps even multiple timers in same script, but . . . starting/stopping/resetting individual ones is a bit difficult. You'd ether have to have dedicated terminal window with multiple tabs or use something like byobu multiplexer or "terminator" terminal emulator to have several splits in the same window. – Sergiy Kolodyazhnyy Sep 25 '16 at 2:27
  • adding/stopping/resetting individual ones in theory can be done with ncurses library and in C, but not in bash – Sergiy Kolodyazhnyy Sep 25 '16 at 2:29
  • 1
    If your goal is to decrease dependency on the online app and use something local, I could also think of an indicator for Unity panel that does that. Concurrent/independent items can be done that way. If you specifically want terminal app, it's very hard to achieve for reasons i stated in previous comments – Sergiy Kolodyazhnyy Sep 25 '16 at 2:34
  • @NickWeinberg It looks like the tea timer was planned, but not implemented. Thank you, though. emacs.stackexchange.com/questions/17796/… – somethis Sep 25 '16 at 2:41

From terminal use the "at" command to set your timer, "at" is very flexible for it can be used with both absolute and relative time (for more info: man at):

at now + 1 minute <<<'notify-send ALARM'

"notify-send" will place a notification on your desktop
(feel free to replace it with i.e. "aplay" to make a sound instead of a notification).

| improve this answer | |
  • Great answer, I like the simplicity. Is there any way to display the time left (like a countdown), too? – somethis Oct 13 '16 at 19:31
  • no, not with "at". if you would like to have a shell-window constantly open to be able to check the countdown time, you're probably better of with a while loop and the sleep command. – thom Oct 19 '16 at 10:48

You can combine tmux or screen with termdown.

Termdown is an ncurses timer.

http://www.slashgeek.net/2016/10/25/termdown-cli-countdown-timer-stopwatch/ shows how termdown works.

tmux and screen allow you to run multiple countdowns at once.

I'd make scripts like

termdown 25:00 && mplayer /path/to/sound.mp3

termdown 05:00 && mplayer /path/to/break.mp3

And, I'll execute pomodoro in a tmux or screen window. That way, I can create multiple countdowns.

Do you want notifications? You can combine notification commands with termdown, too.

I'd set up multiple tmux windows for specific timers in advance.

| improve this answer | |
  • Hey there @crocket. Have just found termdown today. If you look at my answer I have now updated it to include the running termdown for that functionality. Just a bit more creature comforts for a more pleasant user experience. – Dreamcat4 Aug 24 '19 at 17:39

There is a bash script here in Ask Ubuntu called multi-timer

multi-timer Progress bar display

peek wash cycle.png


  • Retains configuration between uses.
  • Up to 19 timers run sequentially in a set.
  • Progress bar for each timer.
  • Set of timers can be run multiple times.
  • Progress bar for set.
  • Progress bar for all sets.
  • Optional prompt to start each timer and/or set.
  • Optional pop-up message when each timer and/or set ends.
  • Optional alarm when each timer and/or set ends.
  • Optional lock screen when each timer OR set OR all sets end.
  • Optional interface to Sysmonitor Indicator so Systray shows countdowns.
  • Optional close progress bar display when all sets of timers end.

Visit the link above for screenshots and bash code.

| improve this answer | |

Heres a shell function have come up with today to solve this exact problem for myself. I do happen to think that it works rather well. Full usage instructions are included in the comments.


Now requires a new dependancy, termdown, for displaying a countdown timer in the terminal.

If you want to use this shell function as a script, then just copy paste it into a new file with the #!/bin/sh shebang as line 1. And then at the end of the file call the function as timer "$@" to pass all the cmdline arguments into it.

Hopefully that addresses the previously raised criticism.

timer() {
  # tested on ubuntu 18.04
  # installation: copy-paste this shell function into your ~/.bashrc or ~/.profile

  # program dependencies
  # to install missing dependancies on ubuntu
  #  # sudo apt-get install -y xcowsay
  #  # sudo snap install -y termdown 
  # this shell function also uses `paplay` (for making a beep / ding sound)
  # and `pgrep` for checking when any xcowsay window was clicked on and dismissed
  # (however on ubuntu desktop 18.04, both `paplay` and `pgrep` are already installed by default)

  # usage examples
  # input string is parsed by the unux date command. tested with "date (GNU coreutils) 8.28"
  # ... this version of date seems able to understand and translate these human-readable strings

  # timer "1h1m30s"
  # timer "1h 1m 30s"
  # timer "1 minute 30 seconds"
  # timer "15 minutes"
  # timer "2 hours 30 minutes"

  # timer "00:45:00" # = "45 minutes"
  # timer "00:00:45" # = "45 seconds"
  # timer "1:1:1"    # = 1 hour, 1 minute and 1 second

  # begin

  # convert input string to seconds, and sleep until time is up
  # _seconds="$(local epoch=$(date --utc -d @0 +%F); date --utc -d "$epoch $time" +%s.%09N)"

  if echo "$_time" | grep -q -E '^[0-9]+$'; then
    _date_flag="$(echo "$_time" | sed  -e "s/s/SECONDS/g"  -e "s/m/MINUTES/g"  -e "s/h/HOURS/g")"
    _seconds="$(date -d "1970-01-01 00:00:00 UTC ${_date_flag}" "+%s")"

  _critical="$(echo $_seconds / 10 | bc)"
  if [ $_seconds -lt 60 ]; then

  elif [ $_seconds -lt 100 ]; then

  elif [ $_seconds -lt 200 ]; then

  elif [ $_seconds -lt 300 ]; then

  # sleep _seconds && \
  termdown --critical $_critical --voice en $_seconds && \
    # handle ctrl+c gracefully
    trap "killall -q xcowsay; exit 1" INT

    # display notifications on all monitors, 1 notification per monitor
    i=0; num_monitors="$(xrandr -q| grep " connected" | wc -l)"
    while [ "$i" -lt "$num_monitors" ]; do

      # this cmd displays the notification itself, and is further customizable
      xcowsay --monitor=$i --time=0 --cow-size=large "$time is up" &
      i="$(expr $i + 1)"


    audacious --pause
    # play -v15 "$_sound_file_timer_expired"
    paplay "$_sound_file_timer_expired"

    while true; do
      # detect if any notifications were dismissed, then exit gracefully
      num_cows="$(pgrep -c xcowsay)"
      [ "$(expr $num_monitors - $num_cows)" -gt 0 ] && break
      # make a slowly repeating ding or beep audible alert sound
      paplay "$_sound_file_remind_repeat"
      sleep $_bell_repeat_delay || break

    # dismiss all of the notifications, when displayed on multiple monitors
    killall -q xcowsay
    trap - INT

| improve this answer | |
  • This doesn't need to be a function, so it should be a script. But if you do want to leave it as a function, you should run it in a subshell to prevent affecting the variables in the interactive shell. – wjandrea Jun 23 '18 at 20:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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