当前运行在你的机器里的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,这个特性还没有实现. |