彩色脚本
- 目录
-
33.5. 彩色脚本
--------------
ANSI [1] 定义了屏幕属性的转义序列集合,例如粗体文本,背景和前景颜色. DOS批处理文
件(batch files) 一般使用ANSI的转义代码来控制色彩输出,Bash脚本也是这么做的.
Example 33-11 一个 "彩色的" 地址资料库
################################Start
Script#######################################
1 #!/bin/bash
2 # ex30a.sh: ex30.sh的"彩色" 版本.
3
#
没有加工处理的地址资料库
4
5
6
clear
# 清除屏幕.
7
8 echo -n "
"
9 echo -e '\E[37;44m'"\033[1mContact List\033[0m"
10
# 白色为前景色,蓝色为背景色
11 echo; echo
12 echo -e "\033[1mChoose one of the following persons:\033[0m"
13
# 粗体
14 tput sgr0
15 echo "(Enter only the first letter of name.)"
16 echo
17 echo -en '\E[47;34m'"\033[1mE\033[0m" # 蓝色
18 tput
sgr0
# 把色彩设置为"常规"
19 echo "vans,
Roland"
# "[E]vans, Roland"
20 echo -en '\E[47;35m'"\033[1mJ\033[0m" # 红紫色
21 tput sgr0
22 echo "ones, Mildred"
23 echo -en '\E[47;32m'"\033[1mS\033[0m" # 绿色
24 tput sgr0
25 echo "mith, Julie"
26 echo -en '\E[47;31m'"\033[1mZ\033[0m" # 红色
27 tput sgr0
28 echo "ane, Morris"
29 echo
30
31 read person
32
33 case "$person" in
34 # 注意变量被引起来了.
35
36 "E" | "e" )
37 # 接受大小写的输入.
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 # 稍后为 Smith 和 Zane 增加信息.
61
62 * )
63 # 默认选项Default option.
64 # 空的输入(直接按了回车) 也会匹配这儿.
65 echo
66 echo "Not yet in database."
67 ;;
68
69 esac
70
71 tput
sgr0
# 把色彩重设为"常规".
72
73 echo
74
75 exit 0
################################End
Script#########################################
Example 33-12 画盒子
################################Start
Script#######################################
1 #!/bin/bash
2 # Draw-box.sh: 用ASCII字符画一个盒子.
3
4 # Stefano Palmeri编写,文档作者作了少量编辑.
5 # 征得作者同意在本书使用.
6
7
8
######################################################################
9 ### draw_box 函数的注释 ###
10
11 # "draw_box" 函数使用户可以在终端上画一个盒子.
12 #
13 #
14 # 用法: draw_box ROW COLUMN HEIGHT WIDTH [COLOR]
15 # ROW 和 COLUMN
定位要画的盒子的左上角.
16 #
17 # ROW 和 COLUMN 必须要大于0且小于目前终端的尺寸.
18 #
19 # HEIGHT 是盒子的行数,必须 > 0.
20 # HEIGHT + ROW 必须 <= 终端的高度.
21 # WIDTH 是盒子的列数,必须 > 0.
22 # WIDTH + COLUMN 必须 <= 终端的宽度.
23 #
24 # 例如: 如果你当前终端的尺寸是 20x80,
25 # draw_box 2 3 10 45 是合法的
26 # draw_box 2 3 19 45 的 HEIGHT 值是错的 (19+2 > 20)
27 # draw_box 2 3 18 78 的 WIDTH 值是错的 (78+3 > 80)
28 #
29 # COLOR 是盒子边框的颜色.
30 # 它是第5个参数,并且它是可选的.
31 # 0=黑色 1=红色 2=绿色 3=棕褐色 4=蓝色 5=紫色 6=青色 7=白色.
32 # 如果你传给这个函数错的参数,
33 #+ 它就会以代码65退出,
34 #+ 没有其他的信息打印到标准出错上.
35 #
36 # 在画盒子之前要清屏.
37 # 函数内不包含有清屏命令.
38 # 这使用户可以画多个盒子,甚至叠接多个盒子.
39
40 ### draw_box 函数注释结束 ###
41
######################################################################
42
43 draw_box(){
44
45 #=============#
46 HORZ="-"
47 VERT="|"
48 CORNER_CHAR="+"
49
50 MINARGS=4
51 E_BADARGS=65
52 #=============#
53
54
55 if [ $# -lt "$MINARGS" ];
then
# 如果参数小于4,退出.
56 exit $E_BADARGS
57 fi
58
59 # 搜寻参数中的非数字的字符.
60 # 能用其他更好的办法吗 (留给读者的练习?).
61 if echo $@ | tr -d [:blank:] | tr -d [:digit:] | grep .
&> /dev/null; then
62 exit $E_BADARGS
63 fi
64
65 BOX_HEIGHT=`expr $3 - 1` # -1
是需要的,因为因为边角的"+"是高和宽共有的部分.
66 BOX_WIDTH=`expr $4 - 1` #
67 T_ROWS=`tput lines`
# 定义当前终端长和宽的尺寸,
68 T_COLS=`tput
cols` #
69
70 if [ $1 -lt 1 ] || [ $1 -gt $T_ROWS ]; then
# 如果参数是数字就开始检查有效性.
71 exit
$E_BADARGS
#
72 fi
73 if [ $2 -lt 1 ] || [ $2 -gt $T_COLS ]; then
74 exit $E_BADARGS
75 fi
76 if [ `expr $1 + $BOX_HEIGHT + 1` -gt $T_ROWS ]; then
77 exit $E_BADARGS
78 fi
79 if [ `expr $2 + $BOX_WIDTH + 1` -gt $T_COLS ]; then
80 exit $E_BADARGS
81 fi
82 if [ $3 -lt 1 ] || [ $4 -lt 1 ]; then
83 exit $E_BADARGS
84
fi
# 参数检查完毕.
85
86
plot_char(){
# 函数内的函数.
87 echo -e "\E[${1};${2}H"$3
88 }
89
90 echo -ne
"\E[3${5}m"
# 如果传递了盒子边框颜色参数,则设置它.
91
92 # start drawing the box
93
94
count=1
# 用plot_char函数画垂直线
95 for (( r=$1; count<=$BOX_HEIGHT; r++));
do #
96 plot_char $r $2 $VERT
97 let count=count+1
98 done
99
100 count=1
101 c=`expr $2 + $BOX_WIDTH`
102 for (( r=$1; count<=$BOX_HEIGHT; r++)); do
103 plot_char $r $c $VERT
104 let count=count+1
105 done
106
107
count=1
# 用plot_char函数画水平线
108 for (( c=$2; count<=$BOX_WIDTH; c++));
do #
109 plot_char $1 $c $HORZ
110 let count=count+1
111 done
112
113 count=1
114 r=`expr $1 + $BOX_HEIGHT`
115 for (( c=$2; count<=$BOX_WIDTH; c++)); do
116 plot_char $r $c $HORZ
117 let count=count+1
118 done
119
120 plot_char $1 $2
$CORNER_CHAR
# 画盒子的角.
121 plot_char $1 `expr $2 + $BOX_WIDTH` +
122 plot_char `expr $1 + $BOX_HEIGHT` $2 +
123 plot_char `expr $1 + $BOX_HEIGHT` `expr $2 + $BOX_WIDTH` +
124
125 echo -ne
"\E[0m"
# 恢复最初的颜色.
126
127 P_ROWS=`expr $T_ROWS - 1` # 在终端的底部打印提示符.
128
129 echo -e "\E[${P_ROWS};1H"
130 }
131
132
133 # 现在, 让我们来画一个盒子.
134
clear
# 清屏.
135 R=2 # 行
136 C=3 # 列
137 H=10 # 高
138 W=45 # 宽
139 col=1 # 颜色(红)
140 draw_box $R $C $H $W $col # 画盒子.
141
142 exit 0
143
144 # 练习:
145 # --------
146 # 增加可以在盒子里打印文本的选项
################################End
Script#########################################
最简单也可能是最有用的ANSI转义序列是加粗文本, \033[1m ... \033[0m. \033 触发转义序
列, 而 "[1" 启用加粗属性, 而"[0" 表示切换回禁用加粗状态. "m"则表示终止一个转义序列.
bash$ echo -e "\033[1mThis is bold text.\033[0m"
一种相似的转义序列可切换下划线效果 (在 rxvt 和 aterm 上).
bash$ echo -e "\033[4mThis is underlined text.\033[0m"
注意: echo使用-e选项可以启用转义序列.
其他的转义序列可用于更改文本或/和背景色彩.
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
注意: 通常为淡色的前景色文本设置粗体效果是较好的.
tput sgr0 把终端设置恢复为原样. 如果省略这一句会使后续在该终端的输出仍为蓝色.
注意: 因为tput sgr0 在某些环境下不能恢复终端设置, echo -ne \E[0m 会是更好的选择.
可以在有色的背景上用下面的模板写有色彩的文本.
echo -e '\E[COLOR1;COLOR2mSome text goes here.'
"\E[" 开始转义序列. 分号分隔的数值"COLOR1" 和 "COLOR2" 指定前景色和背景色, 数值和
色彩的对应参见下面的表格. (数值的顺序不是有关系的,因为前景色和背景色数值都落在不
重叠的范围里.) "m"终止该转义序列, 然后文本以结束的转义指定的属性显示.
也要注意到用单引号引用了echo -e后面的余下命令序列.
下表的数值是在 rxvt 终端运行的结果. 具体效果可能在其他的各种终端上不一样.
table 33-1. 转义序列中数值和彩色的对应
==========================
| 色彩 | 前景色 | 背景色|
| 黑 | 30 | 40 |
| 红 | 31 | 41 |
| 绿 | 32 | 42 |
| 黄 | 33 | 43 |
| 蓝 | 34 | 44 |
| 洋红 | 35 | 45 |
| 青 | 36 | 46 |
| 白 | 37 | 47 |
==========================
Example 33-13 显示彩色文本
################################Start
Script#######################################
1 #!/bin/bash
2 # color-echo.sh: 用彩色来显示文本.
3
4 # 依照需要修改这个脚本.
5 # 这比手写彩色的代码更容易一些.
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" #
把文本属性重设回原来没有清屏前的
18
#
19
20
21 cecho
()
# Color-echo.
22
# 参数 $1 = 要显示的信息
23
# 参数 $2 = 颜色
24 {
25 local default_msg="No message passed."
26
# 不是非要一个本地变量.
27
28 message=${1:-$default_msg} # 默认的信息.
29
color=${2:-$black}
# 如果没有指定,默认使用黑色.
30
31 echo -e "$color"
32 echo "$message"
33
Reset
# 重设文本属性.
34
35 return
36 }
37
38
39 # 现在,让我们试试.
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 # 缺失 $color (色彩)参数.
48 cecho "\"Empty\" color passed (defaults to black)." ""
49 # 空的 $color (色彩)参数.
50 cecho
51 # $message(信息) 和 $color
(色彩)参数都缺失.
52 cecho "" ""
53 # 空的 $message (信息)和 $color
(色彩)参数.
54 # ----------------------------------------------------
55
56 echo
57
58 exit 0
59
60 # 练习:
61 # ---------
62 # 1) 为'cecho ()'函数增加粗体的效果.
63 # 2) 增加可选的彩色背景.
################################End
Script#########################################
Example 33-14 "赛马" 游戏
################################Start
Script#######################################
1 #!/bin/bash
2 # horserace.sh: 非常简单的赛马模拟.
3 # 作者: Stefano Palmeri
4 # 已取得使用许可.
5
6
################################################################
7 # 脚本目的:
8 # 使用转义字符和终端颜色.
9 #
10 # 练习:
11 # 编辑脚本使其更具有随机性,
12 #+ 设置一个假的赌场 . . .
13 # 嗯 . . . 嗯 . . . 这个开始使我想起了一部电影 . . .
14 #
15 # 脚本给每匹马一个随机的障碍.
16 # 不均等会以障碍来计算
17 #+ 并且用一种欧洲风格表达出来.
18 # 例如: 机率(odds)=3.75 意味着如果你押1美元赢,
19 #+ 你可以赢得3.75美元.
20 #
21 # 脚本已经在GNU/Linux操作系统上测试过 OS,
22 #+ 测试终端有xterm 和 rxvt, 及 konsole.
23 # 测试机器有AMD 900 MHz 的处理器,
24 #+ 平均比赛时间是75秒.
25 # 在更快的计算机上比赛时间应该会更低.
26 # 所以, 如果你想有更多的悬念,重设USLEEP_ARG 变量的值.
27 #
28 # 由Stefano Palmeri编写.
29
################################################################
30
31 E_RUNERR=65
32
33 # 检查 md5sum 和 bc 是不是安装了.
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 # 更改下面的变量值可以使脚本执行的更慢.
46 # 它会作为usleep的参数 (man usleep)
47 #+ 并且它的单位是微秒 (500000微秒 = 半秒).
48 USLEEP_ARG=0
49
50 # 如果脚本接收到ctrl-c中断,清除临时目录, 恢复终端光标和颜色
51 #
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 # 参考调试的章节了解'trap'的更多解释
55
56 # 给脚本设置一个唯一(实际不是绝对唯一的)的临时目录名.
57 HORSE_RACE_TMP_DIR=$HOME/.horserace-`date +%s`-`head -c10
/dev/urandom | md5sum | head -c30`
58
59 # 创建临时目录,并切换到该目录下.
60 mkdir $HORSE_RACE_TMP_DIR
61 cd $HORSE_RACE_TMP_DIR
62
63
64 # 这个函数把光标移动到行为 $1 列为 $2 然后打印 $3.
65 # 例如: "move_and_echo 5 10 linux" 等同于
66 #+ "tput cup 4 9; echo linux", 但是用一个命令代替了两个.
67 # 注: "tput cup" 表示在终端左上角的 0 0 位置,
68 #+ echo 是在终端的左上角的 1 1 位置.
69 move_and_echo() {
70
echo -ne "\E[${1};${2}H""$3"
71 }
72
73 # 产生1-9之间伪随机数的函数.
74 random_1_9 () {
75
head -c10 /dev/urandom | md5sum | tr -d [a-z] | tr -d 0 | cut -c1
76 }
77
78 # 画马时模拟运动的两个函数.
79 draw_horse_one() {
80
echo -n " "//$MOVE_HORSE//
81 }
82 draw_horse_two(){
83
echo -n " "\\\\$MOVE_HORSE\\\\
84 }
85
86
87 # 取得当前的终端尺寸.
88 N_COLS=`tput cols`
89 N_LINES=`tput lines`
90
91 # 至少需要 20-行 X 80-列 的终端尺寸. 检查一下.
92 if [ $N_COLS -lt 80 ] || [ $N_LINES -lt 20 ]; then
93 echo "`basename $0` needs a 80-cols X
20-lines terminal."
94 echo "Your terminal is ${N_COLS}-cols X
${N_LINES}-lines."
95 exit $E_RUNERR
96 fi
97
98
99 # 开始画赛场.
100
101 # 需要一个80个字符的字符串,看下面的.
102 BLANK80=`seq -s "" 100 | head -c80`
103
104 clear
105
106 # 把前景和背景颜色设置成白色的.
107 echo -ne '\E[37;47m'
108
109 # 把光标移到终端的左上角.
110 tput cup 0 0
111
112 # 画六条白线.
113 for n in `seq 5`; do
114 echo
$BLANK80 # 线是用80个字符组成的字符串.
115 done
116
117 # 把前景色设置成黑色.
118 echo -ne '\E[30m'
119
120 move_and_echo 3 1 "START
1"
121 move_and_echo 3 75 FINISH
122 move_and_echo 1 5 "|"
123 move_and_echo 1 80 "|"
124 move_and_echo 2 5 "|"
125 move_and_echo 2 80 "|"
126 move_and_echo 4 5 "| 2"
127 move_and_echo 4 80 "|"
128 move_and_echo 5 5 "V 3"
129 move_and_echo 5 80 "V"
130
131 # 把前景色设置成红色.
132 echo -ne '\E[31m'
133
134 # 一些ASCII艺术.
135 move_and_echo 1 8 "..@@@..@@@@@...@@@@@.@...@..@@@@..."
136 move_and_echo 2 8 ".@...@...@.......@...@...@.@......."
137 move_and_echo 3 8 ".@@@@@...@.......@...@@@@@.@@@@...."
138 move_and_echo 4 8 ".@...@...@.......@...@...@.@......."
139 move_and_echo 5 8 ".@...@...@.......@...@...@..@@@@..."
140 move_and_echo 1 43 "@@@@...@@@...@@@@..@@@@..@@@@."
141 move_and_echo 2 43 "@...@.@...@.@.....@.....@....."
142 move_and_echo 3 43 "@@@@..@@@@@.@.....@@@@...@@@.."
143 move_and_echo 4 43 "@..@..@...@.@.....@.........@."
144 move_and_echo 5 43 "@...@.@...@..@@@@..@@@@.@@@@.."
145
146
147 # 把前景和背景颜色设为绿色.
148 echo -ne '\E[32;42m'
149
150 # 画11行绿线.
151 tput cup 5 0
152 for n in `seq 11`; do
153 echo $BLANK80
154 done
155
156 # 把前景色设为黑色.
157 echo -ne '\E[30m'
158 tput cup 5 0
159
160 # 画栅栏.
161 echo "++++++++++++++++++++++++++++++++++++++\
162 ++++++++++++++++++++++++++++++++++++++++++"
163
164 tput cup 15 0
165 echo "++++++++++++++++++++++++++++++++++++++\
166 ++++++++++++++++++++++++++++++++++++++++++"
167
168 # 把前景和背景色设回白色.
169 echo -ne '\E[37;47m'
170
171 # 画3条白线.
172 for n in `seq 3`; do
173 echo $BLANK80
174 done
175
176 # 把前景色设为黑色.
177 echo -ne '\E[30m'
178
179 # 创建9个文件来保存障碍物.
180 for n in `seq 10 7 68`; do
181 touch $n
182 done
183
184 # 设置脚本要画的马的类型为第一种类型.
185 HORSE_TYPE=2
186
187 # 为每匹马创建位置文件和机率文件.
188 #+ 在这些文件里保存了该匹马当前的位置,
189 #+ 类型和机率.
190 for HN in `seq 9`; do
191 touch horse_${HN}_position
192 touch odds_${HN}
193 echo \-1 >
horse_${HN}_position
194 echo $HORSE_TYPE >>
horse_${HN}_position
195 # 给马定义随机的障碍物.
196 HANDICAP=`random_1_9`
197 # 检查random_1_9函数是否返回了有效值.
198 while ! echo $HANDICAP | grep
[1-9] &> /dev/null; do
199
HANDICAP=`random_1_9`
200 done
201 # 给马定义最后的障碍的位置.
202 LHP=`expr $HANDICAP \* 7 + 3`
203 for FILE in `seq 10 7 $LHP`; do
204
echo $HN >> $FILE
205 done
206
207 # 计算机率.
208 case $HANDICAP in
209
1) ODDS=`echo $HANDICAP \* 0.25 + 1.25 | bc`
210
echo $ODDS > odds_${HN}
211
;;
212
2 | 3) ODDS=`echo $HANDICAP \* 0.40 + 1.25 | bc`
213
echo $ODDS > odds_${HN}
214
;;
215
4 | 5 | 6) ODDS=`echo $HANDICAP \* 0.55 + 1.25 | bc`
216
echo $ODDS > odds_${HN}
217
;;
218
7 | 8) ODDS=`echo $HANDICAP \* 0.75 + 1.25 | bc`
219
echo $ODDS > odds_${HN}
220
;;
221
9) ODDS=`echo $HANDICAP \* 0.90 + 1.25 | bc`
222
echo $ODDS > odds_${HN}
223 esac
224
225
226 done
227
228
229 # 打印机率.
230 print_odds() {
231 tput cup 6 0
232 echo -ne '\E[30;42m'
233 for HN in `seq 9`; do
234 echo "#$HN odds->" `cat
odds_${HN}`
235 done
236 }
237
238 # 在起跑线上画马.
239 draw_horses() {
240 tput cup 6 0
241 echo -ne '\E[30;42m'
242 for HN in `seq 9`; do
243 echo
/\\$HN/\\"
"
244 done
245 }
246
247 print_odds
248
249 echo -ne '\E[47m'
250 # 等待回车按键开始赛马.
251 # 转义序列'\E[?25l'禁显了光标.
252 tput cup 17 0
253 echo -e '\E[?25l'Press [enter] key to start the race...
254 read -s
255
256 # 禁用了终端的常规显示功能.
257 # 这避免了赛跑时不小心按了按键键入显示字符而弄乱了屏幕.
258 #
259 stty -echo
260
261 # --------------------------------------------------------
262 # 开始赛跑.
263
264 draw_horses
265 echo -ne '\E[37;47m'
266 move_and_echo 18 1 $BLANK80
267 echo -ne '\E[30m'
268 move_and_echo 18 1 Starting...
269 sleep 1
270
271 # 设置终点线的列数.
272 WINNING_POS=74
273
274 # 记录赛跑开始的时间.
275 START_TIME=`date +%s`
276
277 # COL 是由下面的"while"结构使用的.
278 COL=0
279
280 while [ $COL -lt $WINNING_POS ]; do
281
282
MOVE_HORSE=0
283
284 #
检查random_1_9函数是否返回了有效值.
285 while !
echo $MOVE_HORSE | grep [1-9] &> /dev/null; do
286
MOVE_HORSE=`random_1_9`
287 done
288
289 #
取得随机取得的马的类型和当前位置.
290
HORSE_TYPE=`cat horse_${MOVE_HORSE}_position | tail -1`
291
COL=$(expr `cat horse_${MOVE_HORSE}_position | head -1`)
292
293
ADD_POS=1
294 #
检查当前的位置是否是障碍物的位置.
295 if seq
10 7 68 | grep -w $COL &> /dev/null; then
296
if grep -w $MOVE_HORSE $COL &> /dev/null; then
297
ADD_POS=0
298
grep -v -w $MOVE_HORSE $COL > ${COL}_new
299
rm -f $COL
300
mv -f ${COL}_new $COL
301
else ADD_POS=1
302
fi
303 else
ADD_POS=1
304 fi
305
COL=`expr $COL + $ADD_POS`
306 echo
$COL > horse_${MOVE_HORSE}_position # 保存新位置.
307
308 #
选择要画的马的类型.
309 case
$HORSE_TYPE in
310
1) HORSE_TYPE=2; DRAW_HORSE=draw_horse_two
311
;;
312
2) HORSE_TYPE=1; DRAW_HORSE=draw_horse_one
313
esac
314 echo
$HORSE_TYPE >> horse_${MOVE_HORSE}_position # 保存当前类型.
315
316 #
把前景色设为黑,背景色设为绿.
317 echo
-ne '\E[30;42m'
318
319 #
把光标位置移到新的马的位置.
320 tput
cup `expr $MOVE_HORSE + 5` `cat
horse_${MOVE_HORSE}_position | head -1`
321
322 # 画马.
323
$DRAW_HORSE
324
usleep $USLEEP_ARG
325
326 #
当所有的马都越过15行的之后,再次打印机率.
327
touch fieldline15
328
if [ $COL = 15 ]; then
329
echo $MOVE_HORSE >> fieldline15
330 fi
331
if [ `wc -l fieldline15 | cut -f1 -d " "` = 9 ]; then
332
print_odds
333
: > fieldline15
334
fi
335
336 #
取得领头的马.
337
HIGHEST_POS=`cat *position | sort -n | tail
-1`
338
339 #
把背景色重设为白色.
340 echo
-ne '\E[47m'
341 tput
cup 17 0
342 echo -n
Current leader: `grep -w $HIGHEST_POS *position | cut
-c7`"
"
343
344 done
345
346 # 取得赛马结束的时间.
347 FINISH_TIME=`date +%s`
348
349 # 背景色设为绿色并且启用闪动的功能.
350 echo -ne '\E[30;42m'
351 echo -en '\E[5m'
352
353 # 使获胜的马闪动.
354 tput cup `expr $MOVE_HORSE + 5` `cat
horse_${MOVE_HORSE}_position | head -1`
355 $DRAW_HORSE
356
357 # 禁用闪动文本.
358 echo -en '\E[25m'
359
360 # 把前景和背景色设为白色.
361 echo -ne '\E[37;47m'
362 move_and_echo 18 1 $BLANK80
363
364 # 前景色设为黑色.
365 echo -ne '\E[30m'
366
367 # 闪动获胜的马.
368 tput cup 17 0
369 echo -e "\E[5mWINNER: $MOVE_HORSE\E[25m"" Odds: `cat
odds_${MOVE_HORSE}`"\
370 " Race time: `expr $FINISH_TIME - $START_TIME` secs"
371
372 # 恢复光标和最初的颜色.
373 echo -en "\E[?25h"
374 echo -en "\E[0m"
375
376 # 恢复回显功能.
377 stty echo
378
379 # 删除赛跑的临时文件.
380 rm -rf $HORSE_RACE_TMP_DIR
381
382 tput cup 19 0
383
384 exit 0
################################End
Script#########################################
参考 例子 A-22.
注意: 然而,有一个主要的问题,那就是ANSI 转义序列是不可移植的. 在一些终端运行的
很好的代码可能在另外一些终端上可能运行地很糟糕. 在彩色脚本作者终端上运行的
很好的脚本可能在另外一些终端上就产生不可阅读的输出了. 这给彩色脚本的用处大
大打了个折扣,而很可能使这些技术变成一个暗机关或只是一个玩具而已.
Moshe Jacobson的颜色工具(http://runslinux.net/projects.html#color)能相当容易地使用
ANSI转义序列. 它用清晰和较有逻辑的语法来代替刚才讨论的难用的结构.
Henry/teikedvl 也同样开发了一个软件包来简化彩色脚本的一些操作
(http://scriptechocolor.sourceforge.net/).
注意事项:
[1] 当然,ANSI是American National Standards Institute(美国国家标准组织)的缩
写. 这个令人敬畏的组织建立和维护着许多技术和工业的标准.