34.5. "Colorizing" Scripts

The ANSI [1] escape sequences set screen attributes, such as bold text, and color of foreground and background. DOS batch files commonly used ANSI escape codes for color output, and so can Bash scripts.


Example 34-8. A "colorized" address database

   1 #!/bin/bash
   2 # ex30a.sh: "Colorized" version of ex30.sh.
   3 #            Crude address database
   4 
   5 
   6 clear                                   # Clear the screen.
   7 
   8 echo -n "          "
   9 echo -e '\E[37;44m'"\033[1mContact List\033[0m"
  10                                         # White on blue background
  11 echo; echo
  12 echo -e "\033[1mChoose one of the following persons:\033[0m"
  13                                         # Bold
  14 tput sgr0
  15 echo "(Enter only the first letter of name.)"
  16 echo
  17 echo -en '\E[47;34m'"\033[1mE\033[0m"   # Blue
  18 tput sgr0                               # Reset colors to "normal."
  19 echo "vans, Roland"                     # "[E]vans, Roland"
  20 echo -en '\E[47;35m'"\033[1mJ\033[0m"   # Magenta
  21 tput sgr0
  22 echo "ones, Mildred"
  23 echo -en '\E[47;32m'"\033[1mS\033[0m"   # Green
  24 tput sgr0
  25 echo "mith, Julie"
  26 echo -en '\E[47;31m'"\033[1mZ\033[0m"   # Red
  27 tput sgr0
  28 echo "ane, Morris"
  29 echo
  30 
  31 read person
  32 
  33 case "$person" in
  34 # Note variable is quoted.
  35 
  36   "E" | "e" )
  37   # Accept upper or lowercase input.
  38   echo
  39   echo "Roland Evans"
  40   echo "4321 Floppy Dr."
  41   echo "Hardscrabble, CO 80753"
  42   echo "(303) 734-9874"
  43   echo "(303) 734-9892 fax"
  44   echo "revans@zzy.net"
  45   echo "Business partner & old friend"
  46   ;;
  47 
  48   "J" | "j" )
  49   echo
  50   echo "Mildred Jones"
  51   echo "249 E. 7th St., Apt. 19"
  52   echo "New York, NY 10009"
  53   echo "(212) 533-2814"
  54   echo "(212) 533-9972 fax"
  55   echo "milliej@loisaida.com"
  56   echo "Girlfriend"
  57   echo "Birthday: Feb. 11"
  58   ;;
  59 
  60 # Add info for Smith & Zane later.
  61 
  62           * )
  63    # Default option.	  
  64    # Empty input (hitting RETURN) fits here, too.
  65    echo
  66    echo "Not yet in database."
  67   ;;
  68 
  69 esac
  70 
  71 tput sgr0                               # Reset colors to "normal."
  72 
  73 echo
  74 
  75 exit 0

The simplest, and perhaps most useful ANSI escape sequence is bold text, \033[1m ... \033[0m. The \033 represents an escape, the "[1" turns on the bold attribute, while the "[0" switches it off. The "m" terminates each term of the escape sequence.
 bash$ echo -e "\033[1mThis is bold text.\033[0m"
 	      

A similar escape sequence switches on the underline attribute (on an rxvt and and an aterm).
 bash$ echo -e "\033[4mThis is underlined text.\033[0m"
 	      

Note

With an echo, the -e option enables the escape sequences.

Other escape sequences change the text and/or background color.
 bash$ echo -e '\E[34;47mThis prints in blue.'; tput sgr0
 
 
 bash$ echo -e '\E[33;44m'"yellow text on blue background"; tput sgr0
 	      
The tput sgr0 restores the terminal settings to normal. Omitting this lets all subsequent output from that particular terminal remain blue.

The numbers in the following table work for an rxvt terminal. Results may vary for other terminal emulators.


Table 34-1. Numbers representing colors in Escape Sequences

ColorForegroundBackground
black3040
red3141
green3242
yellow3343
blue3444
magenta3545
cyan3646
white3747


Example 34-9. Echoing colored text

   1 #!/bin/bash
   2 # color-echo.sh: Echoing text messages in color.
   3 
   4 # Modify this script for your own purposes.
   5 # It's easier than hand-coding color.
   6 
   7 black='\E[30;47m'
   8 red='\E[31;47m'
   9 green='\E[32;47m'
  10 yellow='\E[33;47m'
  11 blue='\E[34;47m'
  12 magenta='\E[35;47m'
  13 cyan='\E[36;47m'
  14 white='\E[37;47m'
  15 
  16 
  17 alias Reset="tput sgr0"      #  Reset text attributes to normal
  18                              #+ without clearing screen.
  19 
  20 
  21 cecho ()                     # Color-echo.
  22                              # Argument $1 = message
  23                              # Argument $2 = color
  24 {
  25 local default_msg="No message passed."
  26                              # Doesn't really need to be a local variable.
  27 
  28 message=${1:-$default_msg}   # Defaults to default message.
  29 color=${2:-$black}           # Defaults to black, if not specified.
  30 
  31   echo -e "$color"
  32   echo "$message"
  33   Reset                      # Reset to normal.
  34 
  35   return
  36 }  
  37 
  38 
  39 # Now, let's try it out.
  40 # ----------------------------------------------------
  41 cecho "Feeling blue..." $blue
  42 cecho "Magenta looks more like purple." $magenta
  43 cecho "Green with envy." $green
  44 cecho "Seeing red?" $red
  45 cecho "Cyan, more familiarly known as aqua." $cyan
  46 cecho "No color passed (defaults to black)."
  47        # Missing $color argument.
  48 cecho "\"Empty\" color passed (defaults to black)." ""
  49        # Empty $color argument.
  50 cecho
  51        # Missing $message and $color arguments.
  52 cecho "" ""
  53        # Empty $message and $color arguments.
  54 # ----------------------------------------------------
  55 
  56 echo
  57 
  58 exit 0
  59 
  60 # Exercises:
  61 # ---------
  62 # 1) Add the "bold" attribute to the 'cecho ()' function.
  63 # 2) Add options for colored backgrounds.

Caution

There is, however, a major problem with all this. ANSI escape sequences are emphatically non-portable. What works fine on some terminal emulators (or the console) may work differently, or not at all, on others. A "colorized" script that looks stunning on the script author's machine may produce unreadable output on someone else's. This greatly compromises the usefulness of "colorizing" scripts, and possibly relegates this technique to the status of a gimmick or even a "toy".

Moshe Jacobson's color utility (http://runslinux.net/projects/color) considerably simplifies using ANSI escape sequences. It substitutes a clean and logical syntax for the clumsy constructs just discussed.

Notes

[1]

ANSI is, of course, the acronym for the American National Standards Institute.