This
month's Power Tools column shows lots of techniques for
setting shell prompts.
One technique that isn't covered in shell manual pages is the use
of escape sequences to add color, highlighting, or other
effects to some or all of the characters in your prompt.
Escape sequences are also useful in any text you write to
a terminal -- error messages from a program, for instance.
But be sure that the particular terminal you're writing to really
understands the escape sequences you use.
Here's more about all of that.
Some Background
Terminals -- the old-style dedicated displays with a glass screen and a
keyboard -- have been around a long time.
Terminals didn't have a network connection via Ethernet or TCP/IP:
their interface to the computer was with an RS-232-style cable that
carried text: characters encoded as seven- or eight-bit bytes.
Each character written to the wire would be displayed at the next
position from left to right on the screen, on lines that ran from
the top to the bottom.
(Terminal emulator programs, like xterm, simulate a terminal
on a bitmapped graphical display.)
A text editor (like vi) can display lines of text in a
terminal window by simply writing those characters to the window.
But how can it move the cursor, or make some text brighter, or erase
part (or all) of the screen?
It's done by sending escape sequences: special strings of
characters meant to control the terminal.
A terminal watches each input character and, if it's part of
an escape sequence, it interprets that character string as a
command instead of displaying it as text.
A typical escape sequence starts with the character ESC (033 octal),
and we'll see some soon.
Years ago, there were many brands and models of terminals, and each had
its own set of escape sequences.
Some systems, like Digital's VAX/VMS, locked users into buying that
manufacturer's brand of terminal.
Unix solved this programmers' nightmare by assigning each terminal a
terminal type name and building databases of terminal information
called termcap ("terminal capability") and terminfo.
Luckily, in the year 2003 almost everyone uses a terminal compatible with
the ANSI terminal standard, which is like the popular Digital
VT terminal series.
So we won't cover termcap or terminfo
here; we'll assume that you're using one of these semi-standard
terminals or an emulator, and show the literal escape sequences
to control them.
(If this doesn't work for you, get ahold of information about your
terminal -- or a book like
O'Reilly's
termcap & terminfo --
to find the right escape sequences for your system.)
For the name of your current terminal type, type echo $TERM
or printenv TERM at a shell prompt:
If you use several different kinds of terminals, you may need to
test $TERM from a shell setup file -- or use some other method --
to be sure you send the right escape sequences to each terminal.
(For instance, sending color escape sequences to a monochrome
terminal may produce gibberish -- or nothing.)
There's an example of this in the second following section.
ANSI Escape Sequences
Here's how to form an ANSI escape sequence for changing character mode
(bold/normal, colors, and so on).
There are examples in the next section.
-
The sequence starts with the character ESC, which has the octal value 33.
(We'll see how to make ESC in the next section.)
-
Next comes an opening (left) square bracket, [.
-
Next come one or more attributes: the numbers from the table below.
To set more than one attribute with a single escape sequence, separate the
numbers by semicolons (;).
-
The escape sequence ends with a lowercase letter m.
Here are the attribute numbers.
Some of the first few (non-color) values may not work on all terminals.
The color values don't make sense on a monochrome terminal.
| Attribute | Description |
| 0 | Cancel all attributes except foreground/background color |
| 1 | Bright (bold) |
| 2 | Normal (not bold) |
| 4 | Underline |
| 5 | Blink |
| 7 | Reverse video |
| 8 | Concealed (don't display characters) |
| 30 | Make foreground (the characters) black |
| 31 | Make foreground red |
| 32 | Make foreground green |
| 33 | Make foreground yellow |
| 34 | Make foreground blue |
| 35 | Make foreground magenta |
| 36 | Make foreground cyan |
| 37 | Make foreground white |
| 40 | Make background (around the characters) black |
| 41 | Make background red |
| 42 | Make background green |
| 43 | Make background yellow |
| 44 | Make background blue |
| 45 | Make background magenta |
| 46 | Make background cyan |
| 47 | Make background white (you may need 0 instead, or in addition) |
Some Examples
It's possible to put an ESC character directly into a file (like a shell
setup file, a script, or another program).
But, because ESC isn't a normal "printing" character, it may not
appear correctly when you print the file or view it on your screen.
It's better to use a representation of the character if your
language supports it (for instance, in Perl, put \e or
\033 in a string).
Otherwise, create the character and store it in a variable.
Here are three ways to store ESC in a Bourne shell variable named esc:
# For shells whose echo command understands \e or \033:
esc=`echo '\e'`
esc=`echo '\033'`
# For other shells, use tr to translate e to ESC:
esc=`echo e | tr e '\033'`
Here's an example that tests the TERM variable, then sets escape
sequences for starting and ending a bright section of text.
You might use this case statement in your setup file for
bash:
esc=`echo -e '\e'`
case "$TERM" in
xterm|vt100|ansi)
# Monochrome. Use reverse video:
bright="${esc}[7m"
endbright="${esc}[0m"
;;
color-xterm)
# Color. Use red letters on white:
bright="${esc}[31;47m"
# Use black letters on white:
endbright="${esc}[30;47m"
;;
esac
After that setup, for example, you could output the message
ERROR: can't read file, with the word ERROR in bright
text, as follows.
echo "${bright}ERROR${endbright}: can't read file"
Your color-capable xterms may simply set TERM to xterm.
If yours does, and you also use monochrome terminals,
one workaround is to set a different environment
variable -- for instance, MYTERM -- as you invoke the xterm
program.
Here's the Bourne shell syntax:
MYTERM=color-xterm rxterm &
and the C shell syntax:
(setenv MYTERM color-xterm; rxterm &)
Then you can test MYTERM from your shell setup file.