3.30. Bash, version 2

The current version of bash, the one you have running on your machine, is actually version 2. This update of the classic bash scripting language added array variables, string and parameter expansion, and a better method of indirect variable references, among other features.


Example 3-102. String expansion

   1 #!/bin/bash
   2 
   3 # String expansion.
   4 # Introduced in version 2 of bash.
   5 
   6 # Strings of the form $'xxx'
   7 # have the standard escaped characters interpreted. 
   8 
   9 echo $'Ringing bell 3 times \a \a \a'
  10 echo $'Three form feeds \f \f \f'
  11 echo $'10 newlines \n\n\n\n\n\n\n\n\n\n'
  12 
  13 exit 0


Example 3-103. Indirect variable references - the new way

   1 #!/bin/bash
   2 
   3 # Indirect variable referencing.
   4 # This has a few of the attributes of references in C++.
   5 
   6 
   7 a=letter_of_alphabet
   8 letter_of_alphabet=z
   9 
  10 # Direct reference.
  11 echo "a = $a"
  12 
  13 # Indirect reference.
  14 echo "Now a = ${!a}"
  15 # The ${!variable} notation is greatly superior to the old "eval var1=\$$var2"
  16 
  17 echo
  18 
  19 t=table_cell_3
  20 table_cell_3=24
  21 echo "t = ${!t}"
  22 table_cell_3=387
  23 echo "Value of t changed to ${!t}"
  24 # Useful for referencing members
  25 # of an array or table,
  26 # or for simulating a multi-dimensional array.
  27 # An indexing option would have been nice (sigh).
  28 
  29 
  30 exit 0


Example 3-104. Using arrays and other miscellaneous trickery to deal four random hands from a deck of cards

   1 #!/bin/bash2
   2 # Must specify version 2 of bash, else might not work.
   3 
   4 # Cards:
   5 # deals four random hands from a deck of cards.
   6 
   7 UNPICKED=0
   8 PICKED=1
   9 
  10 DUPE_CARD=99
  11 
  12 LOWER_LIMIT=0
  13 UPPER_LIMIT=51
  14 CARDS_IN_SUITE=13
  15 CARDS=52
  16 
  17 declare -a Deck
  18 declare -a Suites
  19 declare -a Cards
  20 # It would have been easier and more intuitive
  21 # with a single, 3-dimensional array. Maybe 
  22 # a future version of bash will support
  23 # multidimensional arrays.
  24 
  25 
  26 initialize_Deck ()
  27 {
  28 i=$LOWER_LIMIT
  29 until [ $i -gt $UPPER_LIMIT ]
  30 do
  31   Deck[i]=$UNPICKED
  32   let "i += 1"
  33 done
  34 # Set each card of "Deck" as unpicked.
  35 echo
  36 }
  37 
  38 initialize_Suites ()
  39 {
  40 Suites[0]=C #Clubs
  41 Suites[1]=D #Diamonds
  42 Suites[2]=H #Hearts
  43 Suites[3]=S #Spades
  44 }
  45 
  46 initialize_Cards ()
  47 {
  48 Cards=(2 3 4 5 6 7 8 9 10 J Q K A)
  49 # Alternate method of initializing array.
  50 }
  51 
  52 pick_a_card ()
  53 {
  54 card_number=$RANDOM
  55 let "card_number %= $CARDS"
  56 if [ ${Deck[card_number]} -eq $UNPICKED ]
  57 then
  58   Deck[card_number]=$PICKED
  59   return $card_number
  60 else  
  61   return $DUPE_CARD
  62 fi
  63 }
  64 
  65 parse_card ()
  66 {
  67 number=$1
  68 let "suite_number = number / CARDS_IN_SUITE"
  69 suite=${Suites[suite_number]}
  70 echo -n "$suite-"
  71 let "card_no = number % CARDS_IN_SUITE"
  72 Card=${Cards[card_no]}
  73 printf %-4s $Card
  74 # Print cards in neat columns.
  75 }
  76 
  77 seed_random ()
  78 {
  79 # Seed random number generator.
  80 seed=`eval date +%s`
  81 let "seed %= 32766"
  82 RANDOM=$seed
  83 }
  84 
  85 deal_cards ()
  86 {
  87 echo
  88 
  89 cards_picked=0
  90 while [ $cards_picked -le $UPPER_LIMIT ]
  91 do
  92   pick_a_card
  93   t=$?
  94 
  95   if [ $t -ne $DUPE_CARD ]
  96   then
  97     parse_card $t
  98 
  99     u=$cards_picked+1
 100     # Change back to 1-based indexing (temporarily).
 101     let "u %= $CARDS_IN_SUITE"
 102     if [ $u -eq 0 ]
 103     then
 104      echo
 105      echo
 106     fi
 107     # Separate hands.
 108 
 109     let "cards_picked += 1"
 110   fi  
 111 done  
 112 
 113 echo
 114 
 115 return 0
 116 }
 117 
 118 
 119 # Structured programming:
 120 # entire program logic modularized in functions.
 121 
 122 #================
 123 seed_random
 124 initialize_Deck
 125 initialize_Suites
 126 initialize_Cards
 127 deal_cards
 128 
 129 exit 0
 130 #================
 131 
 132 
 133 
 134 # Exercise 1:
 135 # Add comments to thoroughly document this script.
 136 
 137 # Exercise 2:
 138 # Revise the script to print out each hand sorted in suites.
 139 # You may add other bells and whistles if you like.
 140 
 141 # Exercise 3:
 142 # Simplify and streamline the logic of the script.