(M)  s i s t e m a   o p e r a c i o n a l   m a g n u x   l i n u x ~/ · documentação · suporte · sobre

 

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

#!/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.