Advanced Bash-Scripting Guide: An in-depth exploration of the art of shell scripting | ||
---|---|---|
Prev | Chapter 33. Miscellany | Next |
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 33-11. 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 # Reset attributes. 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 |
Example 33-12. Drawing a box
1 #!/bin/bash 2 # Draw-box.sh: Drawing a box using ASCII characters. 3 4 # Script by Stefano Palmeri, with minor editing by document author. 5 # Minor edits suggested by Jim Angstadt. 6 # Used in the ABS Guide with permission. 7 8 9 ###################################################################### 10 ### draw_box function doc ### 11 12 # The "draw_box" function lets the user 13 #+ draw a box in a terminal. 14 # 15 # Usage: draw_box ROW COLUMN HEIGHT WIDTH [COLOR] 16 # ROW and COLUMN represent the position 17 #+ of the upper left angle of the box you're going to draw. 18 # ROW and COLUMN must be greater than 0 19 #+ and less than current terminal dimension. 20 # HEIGHT is the number of rows of the box, and must be > 0. 21 # HEIGHT + ROW must be <= than current terminal height. 22 # WIDTH is the number of columns of the box and must be > 0. 23 # WIDTH + COLUMN must be <= than current terminal width. 24 # 25 # E.g.: If your terminal dimension is 20x80, 26 # draw_box 2 3 10 45 is good 27 # draw_box 2 3 19 45 has bad HEIGHT value (19+2 > 20) 28 # draw_box 2 3 18 78 has bad WIDTH value (78+3 > 80) 29 # 30 # COLOR is the color of the box frame. 31 # This is the 5th argument and is optional. 32 # 0=black 1=red 2=green 3=tan 4=blue 5=purple 6=cyan 7=white. 33 # If you pass the function bad arguments, 34 #+ it will just exit with code 65, 35 #+ and no messages will be printed on stderr. 36 # 37 # Clear the terminal before you start to draw a box. 38 # The clear command is not contained within the function. 39 # This allows the user to draw multiple boxes, even overlapping ones. 40 41 ### end of draw_box function doc ### 42 ###################################################################### 43 44 draw_box(){ 45 46 #=============# 47 HORZ="-" 48 VERT="|" 49 CORNER_CHAR="+" 50 51 MINARGS=4 52 E_BADARGS=65 53 #=============# 54 55 56 if [ $# -lt "$MINARGS" ]; then # If args are less than 4, exit. 57 exit $E_BADARGS 58 fi 59 60 # Looking for non digit chars in arguments. 61 # Probably it could be done better (exercise for the reader?). 62 if echo $@ | tr -d [:blank:] | tr -d [:digit:] | grep . &> /dev/null; then 63 exit $E_BADARGS 64 fi 65 66 BOX_HEIGHT=`expr $3 - 1` # -1 correction needed because angle char "+" 67 BOX_WIDTH=`expr $4 - 1` #+ is a part of both box height and width. 68 T_ROWS=`tput lines` # Define current terminal dimension 69 T_COLS=`tput cols` #+ in rows and columns. 70 71 if [ $1 -lt 1 ] || [ $1 -gt $T_ROWS ]; then # Start checking if arguments 72 exit $E_BADARGS #+ are correct. 73 fi 74 if [ $2 -lt 1 ] || [ $2 -gt $T_COLS ]; then 75 exit $E_BADARGS 76 fi 77 if [ `expr $1 + $BOX_HEIGHT + 1` -gt $T_ROWS ]; then 78 exit $E_BADARGS 79 fi 80 if [ `expr $2 + $BOX_WIDTH + 1` -gt $T_COLS ]; then 81 exit $E_BADARGS 82 fi 83 if [ $3 -lt 1 ] || [ $4 -lt 1 ]; then 84 exit $E_BADARGS 85 fi # End checking arguments. 86 87 plot_char(){ # Function within a function. 88 echo -e "\E[${1};${2}H"$3 89 } 90 91 echo -ne "\E[3${5}m" # Set box frame color, if defined. 92 93 # start drawing the box 94 95 count=1 # Draw vertical lines using 96 for (( r=$1; count<=$BOX_HEIGHT; r++)); do #+ plot_char function. 97 plot_char $r $2 $VERT 98 let count=count+1 99 done 100 101 count=1 102 c=`expr $2 + $BOX_WIDTH` 103 for (( r=$1; count<=$BOX_HEIGHT; r++)); do 104 plot_char $r $c $VERT 105 let count=count+1 106 done 107 108 count=1 # Draw horizontal lines using 109 for (( c=$2; count<=$BOX_WIDTH; c++)); do #+ plot_char function. 110 plot_char $1 $c $HORZ 111 let count=count+1 112 done 113 114 count=1 115 r=`expr $1 + $BOX_HEIGHT` 116 for (( c=$2; count<=$BOX_WIDTH; c++)); do 117 plot_char $r $c $HORZ 118 let count=count+1 119 done 120 121 plot_char $1 $2 $CORNER_CHAR # Draw box angles. 122 plot_char $1 `expr $2 + $BOX_WIDTH` $CORNER_CHAR 123 plot_char `expr $1 + $BOX_HEIGHT` $2 $CORNER_CHAR 124 plot_char `expr $1 + $BOX_HEIGHT` `expr $2 + $BOX_WIDTH` $CORNER_CHAR 125 126 echo -ne "\E[0m" # Restore old colors. 127 128 P_ROWS=`expr $T_ROWS - 1` # Put the prompt at bottom of the terminal. 129 130 echo -e "\E[${P_ROWS};1H" 131 } 132 133 134 # Now, let's try drawing a box. 135 clear # Clear the terminal. 136 R=2 # Row 137 C=3 # Column 138 H=10 # Height 139 W=45 # Width 140 col=1 # Color (red) 141 draw_box $R $C $H $W $col # Draw the box. 142 143 exit 0 144 145 # Exercise: 146 # -------- 147 # Add the option of printing text within the drawn box. |
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 an aterm).
bash$ echo -e "\033[4mThis is underlined text.\033[0m" |
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 bash$ echo -e '\E[1;33;44m'"BOLD yellow text on blue background"; tput sgr0 |
It's usually advisable to set the bold attribute for light-colored foreground text. |
The tput sgr0 restores the terminal settings to normal. Omitting this lets all subsequent output from that particular terminal remain blue.
Since tput sgr0 fails to restore terminal settings under certain circumstances, echo -ne \E[0m may be a better choice. |
Use the following template for writing colored text on a colored background. echo -e '\E[COLOR1;COLOR2mSome text goes here.' The "\E[" begins the escape sequence. The semicolon-separated numbers "COLOR1" and "COLOR2" specify a foreground and a background color, according to the table below. (The order of the numbers does not matter, since the foreground and background numbers fall in non-overlapping ranges.) The "m" terminates the escape sequence, and the text begins immediately after that. Note also that single quotes enclose the remainder of the command sequence following the echo -e. |
The numbers in the following table work for an rxvt terminal. Results may vary for other terminal emulators.
Table 33-2. Numbers representing colors in Escape Sequences
Color | Foreground | Background |
---|---|---|
black | 30 | 40 |
red | 31 | 41 |
green | 32 | 42 |
yellow | 33 | 43 |
blue | 34 | 44 |
magenta | 35 | 45 |
cyan | 36 | 46 |
white | 37 | 47 |
Example 33-13. 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. |
Example 33-14. A "horserace" game
1 #!/bin/bash 2 # horserace.sh: Very simple horserace simulation. 3 # Author: Stefano Palmeri 4 # Used with permission. 5 6 ################################################################ 7 # Goals of the script: 8 # playing with escape sequences and terminal colors. 9 # 10 # Exercise: 11 # Edit the script to make it run less randomly, 12 #+ set up a fake betting shop . . . 13 # Um . . . um . . . it's starting to remind me of a movie . . . 14 # 15 # The script gives each horse a random handicap. 16 # The odds are calculated upon horse handicap 17 #+ and are expressed in European(?) style. 18 # E.g., odds=3.75 means that if you bet $1 and win, 19 #+ you receive $3.75. 20 # 21 # The script has been tested with a GNU/Linux OS, 22 #+ using xterm and rxvt, and konsole. 23 # On a machine with an AMD 900 MHz processor, 24 #+ the average race time is 75 seconds. 25 # On faster computers the race time would be lower. 26 # So, if you want more suspense, reset the USLEEP_ARG variable. 27 # 28 # Script by Stefano Palmeri. 29 ################################################################ 30 31 E_RUNERR=65 32 33 # Check if md5sum and bc are installed. 34 if ! which bc &> /dev/null; then 35 echo bc is not installed. 36 echo "Can\'t run . . . " 37 exit $E_RUNERR 38 fi 39 if ! which md5sum &> /dev/null; then 40 echo md5sum is not installed. 41 echo "Can\'t run . . . " 42 exit $E_RUNERR 43 fi 44 45 # Set the following variable to slow down script execution. 46 # It will be passed as the argument for usleep (man usleep) 47 #+ and is expressed in microseconds (500000 = half a second). 48 USLEEP_ARG=0 49 50 # Clean up the temp directory, restore terminal cursor and 51 #+ terminal colors -- if script interrupted by Ctl-C. 52 trap 'echo -en "\E[?25h"; echo -en "\E[0m"; stty echo;\ 53 tput cup 20 0; rm -fr $HORSE_RACE_TMP_DIR' TERM EXIT 54 # See the chapter on debugging for an explanation of 'trap.' 55 56 # Set a unique (paranoid) name for the temp directory the script needs. 57 HORSE_RACE_TMP_DIR=$HOME/.horserace-`date +%s`-`head -c10 /dev/urandom \ 58 | md5sum | head -c30` 59 60 # Create the temp directory and move right in. 61 mkdir $HORSE_RACE_TMP_DIR 62 cd $HORSE_RACE_TMP_DIR 63 64 65 # This function moves the cursor to line $1 column $2 and then prints $3. 66 # E.g.: "move_and_echo 5 10 linux" is equivalent to 67 #+ "tput cup 4 9; echo linux", but with one command instead of two. 68 # Note: "tput cup" defines 0 0 the upper left angle of the terminal, 69 #+ echo defines 1 1 the upper left angle of the terminal. 70 move_and_echo() { 71 echo -ne "\E[${1};${2}H""$3" 72 } 73 74 # Function to generate a pseudo-random number between 1 and 9. 75 random_1_9 () 76 { 77 head -c10 /dev/urandom | md5sum | tr -d [a-z] | tr -d 0 | cut -c1 78 } 79 80 # Two functions that simulate "movement," when drawing the horses. 81 draw_horse_one() { 82 echo -n " "//$MOVE_HORSE// 83 } 84 draw_horse_two(){ 85 echo -n " "\\\\$MOVE_HORSE\\\\ 86 } 87 88 89 # Define current terminal dimension. 90 N_COLS=`tput cols` 91 N_LINES=`tput lines` 92 93 # Need at least a 20-LINES X 80-COLUMNS terminal. Check it. 94 if [ $N_COLS -lt 80 ] || [ $N_LINES -lt 20 ]; then 95 echo "`basename $0` needs a 80-cols X 20-lines terminal." 96 echo "Your terminal is ${N_COLS}-cols X ${N_LINES}-lines." 97 exit $E_RUNERR 98 fi 99 100 101 # Start drawing the race field. 102 103 # Need a string of 80 chars. See below. 104 BLANK80=`seq -s "" 100 | head -c80` 105 106 clear 107 108 # Set foreground and background colors to white. 109 echo -ne '\E[37;47m' 110 111 # Move the cursor on the upper left angle of the terminal. 112 tput cup 0 0 113 114 # Draw six white lines. 115 for n in `seq 5`; do 116 echo $BLANK80 # Use the 80 chars string to colorize the terminal. 117 done 118 119 # Sets foreground color to black. 120 echo -ne '\E[30m' 121 122 move_and_echo 3 1 "START 1" 123 move_and_echo 3 75 FINISH 124 move_and_echo 1 5 "|" 125 move_and_echo 1 80 "|" 126 move_and_echo 2 5 "|" 127 move_and_echo 2 80 "|" 128 move_and_echo 4 5 "| 2" 129 move_and_echo 4 80 "|" 130 move_and_echo 5 5 "V 3" 131 move_and_echo 5 80 "V" 132 133 # Set foreground color to red. 134 echo -ne '\E[31m' 135 136 # Some ASCII art. 137 move_and_echo 1 8 "..@@@..@@@@@...@@@@@.@...@..@@@@..." 138 move_and_echo 2 8 ".@...@...@.......@...@...@.@......." 139 move_and_echo 3 8 ".@@@@@...@.......@...@@@@@.@@@@...." 140 move_and_echo 4 8 ".@...@...@.......@...@...@.@......." 141 move_and_echo 5 8 ".@...@...@.......@...@...@..@@@@..." 142 move_and_echo 1 43 "@@@@...@@@...@@@@..@@@@..@@@@." 143 move_and_echo 2 43 "@...@.@...@.@.....@.....@....." 144 move_and_echo 3 43 "@@@@..@@@@@.@.....@@@@...@@@.." 145 move_and_echo 4 43 "@..@..@...@.@.....@.........@." 146 move_and_echo 5 43 "@...@.@...@..@@@@..@@@@.@@@@.." 147 148 149 # Set foreground and background colors to green. 150 echo -ne '\E[32;42m' 151 152 # Draw eleven green lines. 153 tput cup 5 0 154 for n in `seq 11`; do 155 echo $BLANK80 156 done 157 158 # Set foreground color to black. 159 echo -ne '\E[30m' 160 tput cup 5 0 161 162 # Draw the fences. 163 echo "++++++++++++++++++++++++++++++++++++++\ 164 ++++++++++++++++++++++++++++++++++++++++++" 165 166 tput cup 15 0 167 echo "++++++++++++++++++++++++++++++++++++++\ 168 ++++++++++++++++++++++++++++++++++++++++++" 169 170 # Set foreground and background colors to white. 171 echo -ne '\E[37;47m' 172 173 # Draw three white lines. 174 for n in `seq 3`; do 175 echo $BLANK80 176 done 177 178 # Set foreground color to black. 179 echo -ne '\E[30m' 180 181 # Create 9 files to stores handicaps. 182 for n in `seq 10 7 68`; do 183 touch $n 184 done 185 186 # Set the first type of "horse" the script will draw. 187 HORSE_TYPE=2 188 189 # Create position-file and odds-file for every "horse". 190 #+ In these files, store the current position of the horse, 191 #+ the type and the odds. 192 for HN in `seq 9`; do 193 touch horse_${HN}_position 194 touch odds_${HN} 195 echo \-1 > horse_${HN}_position 196 echo $HORSE_TYPE >> horse_${HN}_position 197 # Define a random handicap for horse. 198 HANDICAP=`random_1_9` 199 # Check if the random_1_9 function returned a good value. 200 while ! echo $HANDICAP | grep [1-9] &> /dev/null; do 201 HANDICAP=`random_1_9` 202 done 203 # Define last handicap position for horse. 204 LHP=`expr $HANDICAP \* 7 + 3` 205 for FILE in `seq 10 7 $LHP`; do 206 echo $HN >> $FILE 207 done 208 209 # Calculate odds. 210 case $HANDICAP in 211 1) ODDS=`echo $HANDICAP \* 0.25 + 1.25 | bc` 212 echo $ODDS > odds_${HN} 213 ;; 214 2 | 3) ODDS=`echo $HANDICAP \* 0.40 + 1.25 | bc` 215 echo $ODDS > odds_${HN} 216 ;; 217 4 | 5 | 6) ODDS=`echo $HANDICAP \* 0.55 + 1.25 | bc` 218 echo $ODDS > odds_${HN} 219 ;; 220 7 | 8) ODDS=`echo $HANDICAP \* 0.75 + 1.25 | bc` 221 echo $ODDS > odds_${HN} 222 ;; 223 9) ODDS=`echo $HANDICAP \* 0.90 + 1.25 | bc` 224 echo $ODDS > odds_${HN} 225 esac 226 227 228 done 229 230 231 # Print odds. 232 print_odds() { 233 tput cup 6 0 234 echo -ne '\E[30;42m' 235 for HN in `seq 9`; do 236 echo "#$HN odds->" `cat odds_${HN}` 237 done 238 } 239 240 # Draw the horses at starting line. 241 draw_horses() { 242 tput cup 6 0 243 echo -ne '\E[30;42m' 244 for HN in `seq 9`; do 245 echo /\\$HN/\\" " 246 done 247 } 248 249 print_odds 250 251 echo -ne '\E[47m' 252 # Wait for a enter key press to start the race. 253 # The escape sequence '\E[?25l' disables the cursor. 254 tput cup 17 0 255 echo -e '\E[?25l'Press [enter] key to start the race... 256 read -s 257 258 # Disable normal echoing in the terminal. 259 # This avoids key presses that might "contaminate" the screen 260 #+ during the race. 261 stty -echo 262 263 # -------------------------------------------------------- 264 # Start the race. 265 266 draw_horses 267 echo -ne '\E[37;47m' 268 move_and_echo 18 1 $BLANK80 269 echo -ne '\E[30m' 270 move_and_echo 18 1 Starting... 271 sleep 1 272 273 # Set the column of the finish line. 274 WINNING_POS=74 275 276 # Define the time the race started. 277 START_TIME=`date +%s` 278 279 # COL variable needed by following "while" construct. 280 COL=0 281 282 while [ $COL -lt $WINNING_POS ]; do 283 284 MOVE_HORSE=0 285 286 # Check if the random_1_9 function has returned a good value. 287 while ! echo $MOVE_HORSE | grep [1-9] &> /dev/null; do 288 MOVE_HORSE=`random_1_9` 289 done 290 291 # Define old type and position of the "randomized horse". 292 HORSE_TYPE=`cat horse_${MOVE_HORSE}_position | tail -n 1` 293 COL=$(expr `cat horse_${MOVE_HORSE}_position | head -n 1`) 294 295 ADD_POS=1 296 # Check if the current position is an handicap position. 297 if seq 10 7 68 | grep -w $COL &> /dev/null; then 298 if grep -w $MOVE_HORSE $COL &> /dev/null; then 299 ADD_POS=0 300 grep -v -w $MOVE_HORSE $COL > ${COL}_new 301 rm -f $COL 302 mv -f ${COL}_new $COL 303 else ADD_POS=1 304 fi 305 else ADD_POS=1 306 fi 307 COL=`expr $COL + $ADD_POS` 308 echo $COL > horse_${MOVE_HORSE}_position # Store new position. 309 310 # Choose the type of horse to draw. 311 case $HORSE_TYPE in 312 1) HORSE_TYPE=2; DRAW_HORSE=draw_horse_two 313 ;; 314 2) HORSE_TYPE=1; DRAW_HORSE=draw_horse_one 315 esac 316 echo $HORSE_TYPE >> horse_${MOVE_HORSE}_position 317 # Store current type. 318 319 # Set foreground color to black and background to green. 320 echo -ne '\E[30;42m' 321 322 # Move the cursor to new horse position. 323 tput cup `expr $MOVE_HORSE + 5` \ 324 `cat horse_${MOVE_HORSE}_position | head -n 1` 325 326 # Draw the horse. 327 $DRAW_HORSE 328 usleep $USLEEP_ARG 329 330 # When all horses have gone beyond field line 15, reprint odds. 331 touch fieldline15 332 if [ $COL = 15 ]; then 333 echo $MOVE_HORSE >> fieldline15 334 fi 335 if [ `wc -l fieldline15 | cut -f1 -d " "` = 9 ]; then 336 print_odds 337 : > fieldline15 338 fi 339 340 # Define the leading horse. 341 HIGHEST_POS=`cat *position | sort -n | tail -1` 342 343 # Set background color to white. 344 echo -ne '\E[47m' 345 tput cup 17 0 346 echo -n Current leader: `grep -w $HIGHEST_POS *position | cut -c7`\ 347 " " 348 349 done 350 351 # Define the time the race finished. 352 FINISH_TIME=`date +%s` 353 354 # Set background color to green and enable blinking text. 355 echo -ne '\E[30;42m' 356 echo -en '\E[5m' 357 358 # Make the winning horse blink. 359 tput cup `expr $MOVE_HORSE + 5` \ 360 `cat horse_${MOVE_HORSE}_position | head -n 1` 361 $DRAW_HORSE 362 363 # Disable blinking text. 364 echo -en '\E[25m' 365 366 # Set foreground and background color to white. 367 echo -ne '\E[37;47m' 368 move_and_echo 18 1 $BLANK80 369 370 # Set foreground color to black. 371 echo -ne '\E[30m' 372 373 # Make winner blink. 374 tput cup 17 0 375 echo -e "\E[5mWINNER: $MOVE_HORSE\E[25m"" Odds: `cat odds_${MOVE_HORSE}`"\ 376 " Race time: `expr $FINISH_TIME - $START_TIME` secs" 377 378 # Restore cursor and old colors. 379 echo -en "\E[?25h" 380 echo -en "\E[0m" 381 382 # Restore echoing. 383 stty echo 384 385 # Remove race temp directory. 386 rm -rf $HORSE_RACE_TMP_DIR 387 388 tput cup 19 0 389 390 exit 0 |
See also Example A-23, Example A-45, and Example A-42.
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 somewhat compromises the usefulness of colorizing scripts, and possibly relegates this technique to the status of a gimmick. Colorized scripts are probably inappropriate in a commercial setting (your supervisor might disapprove). |
Moshe Jacobson's color utility (http://runslinux.net/projects.html#color) considerably simplifies using ANSI escape sequences. It substitutes a clean and logical syntax for the clumsy constructs just discussed.
Henry/teikedvl has likewise created a utility (http://scriptechocolor.sourceforge.net/) to simplify creation of colorized scripts.
[1] | ANSI is, of course, the acronym for the American National Standards Institute. This august body establishes and maintains various technical and industrial standards. |