Escape Sequences: Useful Text that You Can't See

(Not So) Stupid Shell Tricks - Supplemental Page

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, the terminal 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:

% printenv TERM
xterm

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.

  1. The sequence starts with the character ESC, which has the octal value 33. (We'll see how to make ESC in the next section.)
  2. Next comes an opening (left) square bracket, [.
  3. 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 (;).
  4. 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.

AttributeDescription
0Cancel all attributes except foreground/background color
1Bright (bold)
2Normal (not bold)
4Underline
5Blink
7Reverse video
8Concealed (don't display characters)
30Make foreground (the characters) black
31Make foreground red
32Make foreground green
33Make foreground yellow
34Make foreground blue
35Make foreground magenta
36Make foreground cyan
37Make foreground white
40Make background (around the characters) black
41Make background red
42Make background green
43Make background yellow
44Make background blue
45Make background magenta
46Make background cyan
47Make 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.

Jerry Peek is a freelance writer and instructor who has used Unix and Linux for over 20 years. He’s happy to hear from readers; see http://www.jpeek.com/contact.html.

[Read previous article] [Read next article]
[Read Jerry’s other Linux Magazine articles]