当前运行在你的机器里的Bash版本号是版本 2.xx.y 或 3.xx.y.
bash$ echo $BASH_VERSION 2.05.b.0(1)-release |
例子 34-1. 字符串扩展
1 #!/bin/bash 2 3 # 字符串扩展. 4 # Bash版本2引入的特性. 5 6 # 具有$'xxx'格式的字符串 7 #+ 将会解释里面的标准的转义字符. 8 9 echo $'Ringing bell 3 times \a \a \a' 10 # 可能在一些终端只能响铃一次. 11 echo $'Three form feeds \f \f \f' 12 echo $'10 newlines \n\n\n\n\n\n\n\n\n\n' 13 echo $'\102\141\163\150' # Bash 14 # 八进制相等的字符. 15 16 exit 0 |
例子 34-2. 间接变量引用 - 新方法
1 #!/bin/bash
2
3 # 间接变量引用.
4 # 这有点像C++的引用属性.
5
6
7 a=letter_of_alphabet
8 letter_of_alphabet=z
9
10 echo "a = $a" # 直接引用.
11
12 echo "Now a = ${!a}" # 间接引用.
13 # ${!variable} 形式比老的"eval var1=\$$var2"更高级
14
15 echo
16
17 t=table_cell_3
18 table_cell_3=24
19 echo "t = ${!t}" # t = 24
20 table_cell_3=387
21 echo "Value of t changed to ${!t}" # 387
22
23 # 这在用来引用数组或表格的成员时非常有用,
24 #+ 或用来模拟多维数组.
25 # 如果有可索引的选项 (类似于指针运算)
26 #+ 会更好. 唉.
27
28 exit 0 |
例子 34-3. 使用间接变量引用的简单数据库应用
1 #!/bin/bash
2 # resistor-inventory.sh
3 # 使用间接变量引用的简单数据库应用.
4
5 # ============================================================== #
6 # 数据
7
8 B1723_value=470 # 值
9 B1723_powerdissip=.25 # 是什么
10 B1723_colorcode="yellow-violet-brown" # 色彩带宽
11 B1723_loc=173 # 它们存在哪儿
12 B1723_inventory=78 # 有多少
13
14 B1724_value=1000
15 B1724_powerdissip=.25
16 B1724_colorcode="brown-black-red"
17 B1724_loc=24N
18 B1724_inventory=243
19
20 B1725_value=10000
21 B1725_powerdissip=.25
22 B1725_colorcode="brown-black-orange"
23 B1725_loc=24N
24 B1725_inventory=89
25
26 # ============================================================== #
27
28
29 echo
30
31 PS3='Enter catalog number: '
32
33 echo
34
35 select catalog_number in "B1723" "B1724" "B1725"
36 do
37 Inv=${catalog_number}_inventory
38 Val=${catalog_number}_value
39 Pdissip=${catalog_number}_powerdissip
40 Loc=${catalog_number}_loc
41 Ccode=${catalog_number}_colorcode
42
43 echo
44 echo "Catalog number $catalog_number:"
45 echo "There are ${!Inv} of [${!Val} ohm / ${!Pdissip} watt] resistors in stock."
46 echo "These are located in bin # ${!Loc}."
47 echo "Their color code is \"${!Ccode}\"."
48
49 break
50 done
51
52 echo; echo
53
54 # 练习:
55 # ---------
56 # 1) 重写脚本,使其从外部文件里读数据.
57 # 2) 重写脚本,用数组代替间接变量引用
58 #
59 # 用数组会更简单明了
60
61
62 # 注:
63 # -----
64 # Shell脚本除了最简单的数据应用,其实并不合适数据库应用,
65 #+ 它过多地依赖实际工作的环境和命令.
66 # 写数据库应用更好的还是用一门自然支持数据结构的语言,
67 #+ 如 C++ 或 Java (或甚至是 Perl).
68
69 exit 0 |
例子 34-4. 用数组和其他的小技巧来处理四人随机打牌
1 #!/bin/bash
2
3 # Cards:
4 # 处理四人打牌.
5
6 UNPICKED=0
7 PICKED=1
8
9 DUPE_CARD=99
10
11 LOWER_LIMIT=0
12 UPPER_LIMIT=51
13 CARDS_IN_SUIT=13
14 CARDS=52
15
16 declare -a Deck
17 declare -a Suits
18 declare -a Cards
19 # 用一个三维数据来描述数据会更容易实现也更明了一些。
20 #
21 # 可能Bash将来的版本会支持多维数组.
22
23
24 initialize_Deck ()
25 {
26 i=$LOWER_LIMIT
27 until [ "$i" -gt $UPPER_LIMIT ]
28 do
29 Deck[i]=$UNPICKED # 把整副牌的每张牌都设为没人持牌.
30 let "i += 1"
31 done
32 echo
33 }
34
35 initialize_Suits ()
36 {
37 Suits[0]=C #梅花
38 Suits[1]=D #方块
39 Suits[2]=H #红心
40 Suits[3]=S #黑桃
41 }
42
43 initialize_Cards ()
44 {
45 Cards=(2 3 4 5 6 7 8 9 10 J Q K A)
46 # 另一种初始化数组的方法.
47 }
48
49 pick_a_card ()
50 {
51 card_number=$RANDOM
52 let "card_number %= $CARDS"
53 if [ "${Deck[card_number]}" -eq $UNPICKED ]
54 then
55 Deck[card_number]=$PICKED
56 return $card_number
57 else
58 return $DUPE_CARD
59 fi
60 }
61
62 parse_card ()
63 {
64 number=$1
65 let "suit_number = number / CARDS_IN_SUIT"
66 suit=${Suits[suit_number]}
67 echo -n "$suit-"
68 let "card_no = number % CARDS_IN_SUIT"
69 Card=${Cards[card_no]}
70 printf %-4s $Card
71 # 优雅地打印各张牌.
72 }
73
74 seed_random () # 随机产生牌上数值的种子.
75 { # 如果你没有这么做会有什么发生?
76 seed=`eval date +%s`
77 let "seed %= 32766"
78 RANDOM=$seed
79 # 其他的产生随机用的种子的方法还有什么W?
80 #
81 }
82
83 deal_cards ()
84 {
85 echo
86
87 cards_picked=0
88 while [ "$cards_picked" -le $UPPER_LIMIT ]
89 do
90 pick_a_card
91 t=$?
92
93 if [ "$t" -ne $DUPE_CARD ]
94 then
95 parse_card $t
96
97 u=$cards_picked+1
98 # 改回1步进的索引(临时的). 为什么?
99 let "u %= $CARDS_IN_SUIT"
100 if [ "$u" -eq 0 ] # 内嵌的 if/then 条件测试.
101 then
102 echo
103 echo
104 fi
105 # Separate hands.
106
107 let "cards_picked += 1"
108 fi
109 done
110
111 echo
112
113 return 0
114 }
115
116
117 # 结构化编程:
118 # 整个程序逻辑模块化.
119
120 #================
121 seed_random
122 initialize_Deck
123 initialize_Suits
124 initialize_Cards
125 deal_cards
126 #================
127
128 exit 0
129
130
131
132 # 练习 1:
133 # 把这个脚本完整地做注释.
134
135 # 练习 2:
136 # 增加一个处理例程 (函数) 来以花色排序打印出每个人手中的牌.
137 # 如果你高兴,可增加你喜欢的各种酷的代码.
138
139 # 练习 3:
140 # 简化和理顺脚本的逻辑. |
| [1] | Chet Ramey 承诺会在Bash的未来版本中实现关联数组(associative arrays) (一个Perl特性). 到了版本3,这个特性还没有实现. |