This is a read-only archive. Find the latest Linux articles, documentation, and answers at the new Linux.com!

Linux.com

Feature: Tools & Utilities

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

By Sergio Gonzalez Duran on January 22, 2008 (9:00:00 AM)

Share    Print    Comments   

When I'm in a Linux terminal, I often find myself typing date just to see the time. To make life a bit easier, I wrote a script to always display a clock in the top right corner of the screen.

The script saves the current cursor position with an ANSI escape sequence instruction. Then, using the tput command, the cursor is sent to row 0 (the top of the screen) and the last column minus 19 characters (19 is the length of HH:MM:SS YYYY-MM-DD). The formatted date command is displayed in green inverted color. The cursor is then sent back to its original position with another ANSI sequence that restores the original saved position.

If you're in an X Window System terminal, you can resize the window, and the clock will adjust its position because it is displayed at the last column minus 19 characters. The ANSI escape sequences don't work in all terminal emulators, but they do fine in xterm. Here's the script:

#!/bin/bash # clock.sh # the script is executed inside a while without conditions while : do # time and date are formatted to show HH:MM:SS YYYY-MM-DD cmd=`date +"%H:%M:%S %F"` # cursor's current position is saved through an escape sequence echo -n -e "\033[s" # Uncomment the next two lines to clean up the whole first line, although it causes a lot of blinking #tput cup 0 0 # positions on row 0 col 0 (left top corner) #tput el # cleans from position to end of line # to place the clock on the appropriate column, subtract the length of 'HH:MM:SS YYYY-MM-DD', which is 19, # from the total number of columns C=$((`tput cols` - 19)) tput cup 0 $C # positions cursor at row 0 col $C # clock will be shown green inverted # setaf 2 = green, smso = inverted COLOR=`tput setaf 2; tput smso` # back to normal screen colors NORMAL=`tput sgr0` # print the time-date output on the above position echo -n $COLOR$cmd$NORMAL # restore the cursor to whatever was its previous position echo -n -e "\033[u" # script is executed every second sleep 1 done

Save the script as clock.sh, chmod to 755, and run it with ./clock.sh&. The time and date should now appear at the top right of your screen.

When you run clock.sh, the terminal will return the job number and process identifier (PID) of the clock.sh process. You can end the execution of the script by using the kill command and specifying the job number.

With this script, you can display not only a clock, but other useful information as well. For example, suppose you want to monitor your CPU's load average from the uptime command:

uptime 09:19:56 up 1 day, 1:54, 4 users, load average: 0.29, 0.39, 0.42

The last three values are the average load for the last one, five, and 15 minutes. You can extract these values with a gawk command:

uptime | gawk '{print $(NF - 2), $(NF - 1), $NF}' 0.72, 0.54, 0.47

NF is the total number of fields in the output, and $NF is the value of the last field. In clock.sh, change this line:

cmd=`date +"%H:%M:%S %F"`

to this:

cmd=`uptime | gawk '{print $(NF - 2), $(NF - 1), $NF}'`

or this, to leave the time and date:

cmd=`date +"%H:%M:%S %F" ; uptime | gawk '{print $(NF - 2), $(NF - 1), $NF}'`

Since the length of the string is no longer 19, let the wc command help you determine the display offset. Change this line:

C=$((`tput cols` - 19))

to this:

C=$((`tput cols` - (`echo $cmd | wc -c` - 1) ))

The length of the output is calculated with wc -c (the -c option tells wc to count the number of characters in the string being piped to it). -1 subtracts the \r at the end of the $cmd output.

You could also display the total size or available space of a growing partition with df, the number of users online with uptime or w, or the number of processes with ps. Samba, Apache, and many other servers have status commands where you can extract pieces of information to show this way. Use your imagination to create your own modified version of clock.sh.

Sergio Gonzalez Duran is a Linux administrator, systems developer, and network security counselor who also teaches Linux courses and publishes the Spanish-oriented Linux and open source Web site linuxtotal.com.mx.

Share    Print    Comments   

Comments

on CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Note: Comments are owned by the poster. We are not responsible for their content.

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 194.68.126.35] on January 22, 2008 09:54 AM
Cool little script, gonna use it to lean shell scripting

#

Absurd! Use screen

Posted by: Anonymous [ip: 68.126.223.79] on January 22, 2008 10:15 AM
This is ridiculous. Just use screen with this in your screenrc: caption always "%{+b wk}%-21=%D %d.%m.%Y %0c"

#

Re: Absurd! Use screen

Posted by: Anonymous [ip: 80.138.71.49] on January 22, 2008 09:20 PM
and what does that do when you boot to textmode?

#

Re: Absurd! Use screen

Posted by: Anonymous [ip: 134.251.182.21] on February 18, 2008 04:30 AM
It's not absurd: not every system has screen installed... just as not every system has emacs either, so one must learn to work in vi. This little script will work on any term that can understand EMCA-48 escape codes.

#

Splendid - both simple and teaching!

Posted by: Anonymous [ip: 80.203.94.150] on January 22, 2008 11:19 AM
Thank you for the script and careful, professional explanation. Hope to read more such articles in the future. Kind regards and best wishes.

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 87.205.179.17] on January 22, 2008 12:06 PM
Really nice tool. Useful to learn some bash scripting. Thx!:)

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 134.76.62.65] on January 22, 2008 12:06 PM
I prefer PS1="\A \h:\w > ". (Stupid software HTMLizes the preview?)
That way, the clock is always right at the prompt, and I do not have to use some obscure escape sequences or extra script poking onto my tty which may interfere with terminal programs while they are running.

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 60.53.3.62] on January 22, 2008 01:06 PM
This is really elegant. The beauty of it is I never even thought that I'd want a clock in the terminal and now I'm instantly in love with it! Does anyone know if this works in a Mac OS terminal?

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 67.171.149.166] on January 22, 2008 02:04 PM
I usually just look down in the lower right corner of my screen on the task bar to see what time it is, and geez the current date is even there. Absolutely marvelous.

#

Re: CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: unknown] on January 22, 2008 02:16 PM
Well, I wrote the script because most of the time I work in full text mode, no GUI to show the clock. I forget to mention that in the article.

#

Re(1): CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 12.169.163.241] on January 22, 2008 05:13 PM
Ignore the slashdot rejects and their juvenile whining- this is a great script and a good Bash lesson. Thank you!

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 198.185.140.7] on January 22, 2008 03:15 PM
This is a cool little script. I'm planning on trying it out at home. I do put the time in my Bash prompt, but I don't type a command, the time isn't updated.

Thanks for the article.

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 71.236.180.248] on January 22, 2008 03:32 PM
Hmm, interesting use of escape sequences.

I like the time in the prompt, though.. You can tell what time it is and you also have the benefit of knowing how long the last command took.

#

Re: CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 60.53.3.62] on January 23, 2008 09:53 AM
Actually, you can't tell how long the last command took using a clock at the prompt. If you think about for a few seconds, you'll see why.

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 82.95.236.142] on January 22, 2008 05:16 PM
This is what sysline traditionally used to do: time, if I recall correctly, system load,
new mail flag, or really just about anything.
Google for terminal plus sysline or status line. Can be set at bottom or top of
terminal. Basically you're setting a so-called scroll region, and use what's left for
the status line.

Cheers.

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 92.227.68.169] on January 22, 2008 09:07 PM
Nice script, but why do you query the COLOR and NORMAL variables every single second? I mean, they hardly ever change. Simply put that ontop of the while - do loop and your save quite a lot of cycles. The same could be said for the date aquisition: if you sleep 1sec all the time, why not get the time in the beginning, increase secs till 59 and then query again. Every program you call outside of bash uses quite a lot of cycles, if you stay inside of bash (declare -i sec; ...; sec++) you use way less cycles.
With todays CPUs it's close to negligible but nevertheless a better coding style.
Robos

#

Re: CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: unknown] on January 23, 2008 12:03 AM
Very good, with the above changes this nice script consumes less cycles and doesnt blink anymore. Good article and good feedback.

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 58.110.208.227] on January 22, 2008 09:49 PM
Assuming this is a tty ( tty1-6 for instance)

sudo -b vcstime

(or just `vcstime &` as root )

displays a clock in the top right corner of your tty

The script is interesting, but someone already thought of this, as above ... it's part of the console-tools package in Ubuntu, for example.
Probably the same package in Debian.

#

Way too complicated

Posted by: Anonymous [ip: 24.92.13.244] on January 23, 2008 02:45 AM
that is an extremely hackish and complicated way to do it
you can do it in half a line by simply putting this in your shell rc file (.shrc , .bashrc , .zshrc, .tcshrc , etc.)
............................................................................................................................................................................................................................................................................................................................................
export PS1=\[\033[01;31m\]\u@\h \[\033[01;32m\]\@ \[\033[01;34m\]\w $ \[\033[00m\]
....................................................................
I have confirmed this to work on linux,solaris,and mac os x , the dots are so the code is all on one line

#

CLI Magic: Use ANSI escape sequences to annoy your friends

Posted by: Anonymous [ip: 203.2.120.51] on January 23, 2008 05:35 AM
Ahhh memories..many years ago, learning the tput capabilities, I knocked this together. Yes it is crappy code, but I keep it for sentimental value - not for the popular dance it represents but for the nuisance value it had to a friend and co-worker (it used to trap and ignore control-C and found its way into his .profile if he forgot to lock his screen). It is benign but of course never run what you dont understand and trust. Never ever. Ever.
#! /usr/bin/sh -i
POS=`tput cup 0 0`
clear
while [ 1 ]
do
echo "${POS}"
tput bel
echo " o "
echo "^|\ "
echo " /\ "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo "^|^ "
echo " >\ "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo "v|^ "
echo "/< "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo "v|v "
echo " >\ "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo "|/v "
echo "/< "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo "|X| "
echo " >\ "
echo "${POS}"
tput bel
sleep 1
echo "<o "
echo " \| "
echo "/< "
echo "${POS}"
tput bel
sleep 1
echo "<o> "
echo " | "
echo " >\ "
echo "${POS}"
tput bel
sleep 1
echo " o> "
echo " \ "
echo "/< "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo " x "
echo " >\ "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo "</ "
echo "/< "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo "<|> "
echo " >\ "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo "</> "
echo "/< "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo "<\> "
echo " >\ "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo "<)> "
echo " >> "
echo "${POS}"
tput bel
sleep 1
echo " o "
echo " |\ "
echo " L "
done

#

Re: CLI Magic: Use ANSI escape sequences to annoy your friends

Posted by: Anonymous [ip: 203.2.120.51] on January 23, 2008 05:36 AM
Ok, that was apparently never going to work. My apologies. If you can decipher it, enjoy! :)

#

csh/tcsh version of the script

Posted by: Anonymous [ip: 67.127.54.23] on January 23, 2008 06:07 AM
#/usr/bin/tcsh
# clock.tcsh

# the script is executed inside a while without conditions
while 1
# time and date are formatted to show HH:MM:SS YYYY-MM-DD
set cmd = `date +"%H:%M:%S %F"`

# cursor's current position is saved through an escape sequence
echo -n "\033[s"

# Uncomment the next two lines to clean up the whole first line, although it causes a lot of blinking
#tput cup 0 0 # positions on row 0 col 0 (left top corner)
#tput el # cleans from position to end of line

# to place the clock on the appropriate column, subtract the length of 'HH:MM:SS YYYY-MM-DD', which is 19,
# from the total number of columns
set cols = `tput cols`
@ C = ( $cols - 19 )
tput cup 0 $C # positions cursor at row 0 col $C

# clock will be shown green inverted
# setaf 2 = green, smso = inverted
set COLOR = `tput setaf 2; tput smso`

# back to normal screen colors
set NORMAL = `tput sgr0`

# print the time-date output on the above position
echo -n $COLOR$cmd$NORMAL

# restore the cursor to whatever was its previous position
echo -n -e "\033[u"

# script is executed every second
sleep 1
end

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 123.200.203.202] on January 23, 2008 08:32 AM
I like it, but as others have noted, you can just customise your prompt by including the following in .bashrc. I'm fond of this one prompt:

PS1='\[\033[0;32m\]\u@\h\[\033[0m\] \[\033[0;33m\]\w\[\033[0m\]\n\[\033[1;33m\]\@\[\033[0m\]: '


It makes your prompt look like this...


user@host /current/path
07:20 PM: _

In three different colours too.

[[That's not what it looks like - I don't know why this post has no linebreaks.]]

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 192.163.20.231] on January 23, 2008 09:19 AM
Excellent piece of work.!!! ....and really usefull.

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 192.168.1.163] on January 23, 2008 11:59 AM
Pretty nice thing. But it's useful only if your terminal is idle most of the time and you're typing commands from time to time.
Type 'find /' and you will see 'find' output and no time... For a terminal running within X, I would like to see the time, uptime,
load average, etc. in the window title instead (if the window manager decorates the windows in the way enough to do so).

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 75.80.173.93] on January 23, 2008 03:50 PM
most useful when shelling into a server. Nice and thanks.

#

CLI Magic: Use ANSI escape sequences to display a clock in your terminal

Posted by: Anonymous [ip: 10.49.10.87] on January 23, 2008 04:04 PM
I did this in about 1986 using wyse control codes, I stopped because of a few reasons:

1. I got fed up with scrolling applications such as vi or more corrupting the screen if I scrolled back. Sysline provided a better method that set up the scroll regions and reset the terminal height settings so that fullscreen applications still mostly worked, and reworking it to write to the X titlebar is another way of avoiding scroll problems although if you are running X windows then you have better places to put a clock than the top of your window.
2. Writes may not be atomic, which means other background tasks can write to your terminal whilst the cursor is in an odd place. Saving and restoring cursor positions may also cause issues if another application expects to use that functionality. Terminal control codes can also clash causing wierd effects.
3. More horsepower and screen real estate lets me have another window or taskbar with the time in it.

In conclusion - it looks good if you just sit at a prompt not doing anything, but fiddling with an active console causes nothing but tears. The correct answer is to follow the "screen" suggestion above with 'caption always "%{+b wk}%-21=%D %d.%m.%Y %0c"'. This provides all sorts of advantages such as detatching and reattaching sessions that go way beyond a clock. If you're a sysadmin who has had to reboot their frontend whilst a long-running interactive task is in a window then you will love 'screen'.

#

How's about the US population in your terminal...

Posted by: Anonymous [ip: 65.114.240.10] on January 23, 2008 10:04 PM

This story has been archived. Comments can no longer be posted.



 
Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya