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
#!/bin/bash
# String expansion.
# Introduced in version 2 of bash.
# Strings of the form $'xxx'
# have the standard escaped characters interpreted.
echo $'Ringing bell 3 times \a \a \a'
echo $'Three form feeds \f \f \f'
echo $'10 newlines \n\n\n\n\n\n\n\n\n\n'
exit 0 |
Example 3-103. Indirect variable references - the new way
#!/bin/bash
# Indirect variable referencing.
# This has a few of the attributes of references in C++.
a=letter_of_alphabet
letter_of_alphabet=z
# Direct reference.
echo "a = $a"
# Indirect reference.
echo "Now a = ${!a}"
# The ${!variable} notation is greatly superior to the old "eval var1=\$$var2"
echo
t=table_cell_3
table_cell_3=24
echo "t = ${!t}"
table_cell_3=387
echo "Value of t changed to ${!t}"
# Useful for referencing members
# of an array or table,
# or for simulating a multi-dimensional array.
# An indexing option would have been nice (sigh).
exit 0 |
Example 3-104. Using arrays and other miscellaneous trickery
to deal four random hands from a deck of cards
#!/bin/bash2
# Must specify version 2 of bash, else might not work.
# Cards:
# deals four random hands from a deck of cards.
UNPICKED=0
PICKED=1
DUPE_CARD=99
LOWER_LIMIT=0
UPPER_LIMIT=51
CARDS_IN_SUITE=13
CARDS=52
declare -a Deck
declare -a Suites
declare -a Cards
# It would have been easier and more intuitive
# with a single, 3-dimensional array. Maybe
# a future version of bash will support
# multidimensional arrays.
initialize_Deck ()
{
i=$LOWER_LIMIT
until [ $i -gt $UPPER_LIMIT ]
do
Deck[i]=$UNPICKED
let "i += 1"
done
# Set each card of "Deck" as unpicked.
echo
}
initialize_Suites ()
{
Suites[0]=C #Clubs
Suites[1]=D #Diamonds
Suites[2]=H #Hearts
Suites[3]=S #Spades
}
initialize_Cards ()
{
Cards=(2 3 4 5 6 7 8 9 10 J Q K A)
# Alternate method of initializing array.
}
pick_a_card ()
{
card_number=$RANDOM
let "card_number %= $CARDS"
if [ ${Deck[card_number]} -eq $UNPICKED ]
then
Deck[card_number]=$PICKED
return $card_number
else
return $DUPE_CARD
fi
}
parse_card ()
{
number=$1
let "suite_number = number / CARDS_IN_SUITE"
suite=${Suites[suite_number]}
echo -n "$suite-"
let "card_no = number % CARDS_IN_SUITE"
Card=${Cards[card_no]}
printf %-4s $Card
# Print cards in neat columns.
}
seed_random ()
{
# Seed random number generator.
seed=`eval date +%s`
let "seed %= 32766"
RANDOM=$seed
}
deal_cards ()
{
echo
cards_picked=0
while [ $cards_picked -le $UPPER_LIMIT ]
do
pick_a_card
t=$?
if [ $t -ne $DUPE_CARD ]
then
parse_card $t
u=$cards_picked+1
# Change back to 1-based indexing (temporarily).
let "u %= $CARDS_IN_SUITE"
if [ $u -eq 0 ]
then
echo
echo
fi
# Separate hands.
let "cards_picked += 1"
fi
done
echo
return 0
}
# Structured programming:
# entire program logic modularized in functions.
#================
seed_random
initialize_Deck
initialize_Suites
initialize_Cards
deal_cards
exit 0
#================
# Exercise 1:
# Add comments to thoroughly document this script.
# Exercise 2:
# Revise the script to print out each hand sorted in suites.
# You may add other bells and whistles if you like.
# Exercise 3:
# Simplify and streamline the logic of the script. |