Chapter 37. Bash, versions 2, 3, and. Comtrol DeviceMaster Software Development Kit
Reklama
Reklama
Chapter 37. Bash, versions 2, 3, and 4
37.1. Bash, version 2
The current version of Bash, the one you have running on your machine, is most likely version 2.xx.yy,
3.xx.yy, or 4.xx.yy.
bash$
echo $BASH_VERSION
3.2.25(1)-release
The version 2 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 37-1. String expansion
#!/bin/bash
# String expansion.
# Introduced with version 2 of Bash.
# Strings of the form $'xxx'
#+ have the standard escaped characters interpreted. echo $'Ringing bell 3 times \a \a \a'
# May only ring once with certain terminals.
# Or ...
# May not ring at all, depending on terminal settings.
echo $'Three form feeds \f \f \f' echo $'10 newlines \n\n\n\n\n\n\n\n\n\n' echo $'\102\141\163\150'
# B a s h
# Octal equivalent of characters.
exit
Example 37-2. 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 echo "a = $a" # Direct reference.
echo "Now a = ${!a}" # Indirect reference.
# The ${!variable} notation is more intuitive than the old
#+ eval var1=\$$var2 echo
Chapter 37. Bash, versions 2, 3, and 4 544
Advanced Bash-Scripting Guide t=table_cell_3 table_cell_3=24 echo "t = ${!t}" # t = 24 table_cell_3=387 echo "Value of t changed to ${!t}" # 387
# No 'eval' necessary.
# This is useful for referencing members of an array or table,
#+ or for simulating a multi-dimensional array.
# An indexing option (analogous to pointer arithmetic)
#+ would have been nice. Sigh.
exit 0
# See also, ind-ref.sh example.
Example 37-3. Simple database application, using indirect variable referencing
#!/bin/bash
# resistor-inventory.sh
# Simple database / table-lookup application.
# ============================================================== #
# Data
B1723_value=470 # Ohms
B1723_powerdissip=.25 # Watts
B1723_colorcode="yellow-violet-brown" # Color bands
B1723_loc=173 # Where they are
B1723_inventory=78 # How many
B1724_value=1000
B1724_powerdissip=.25
B1724_colorcode="brown-black-red"
B1724_loc=24N
B1724_inventory=243
B1725_value=10000
B1725_powerdissip=.125
B1725_colorcode="brown-black-orange"
B1725_loc=24N
B1725_inventory=89
# ============================================================== # echo
PS3='Enter catalog number: ' echo select catalog_number in "B1723" "B1724" "B1725" do
Inv=${catalog_number}_inventory
Val=${catalog_number}_value
Pdissip=${catalog_number}_powerdissip
Loc=${catalog_number}_loc
Ccode=${catalog_number}_colorcode
Chapter 37. Bash, versions 2, 3, and 4 545
Advanced Bash-Scripting Guide
echo
echo "Catalog number $catalog_number:"
# Now, retrieve value, using indirect referencing.
echo "There are ${!Inv} of [${!Val} ohm / ${!Pdissip} watt]\
resistors in stock." # ^ ^
# As of Bash 4.2, you can replace "ohm" with \u2126 (using echo -e).
echo "These are located in bin # ${!Loc}."
echo "Their color code is \"${!Ccode}\"."
break done echo; echo
# Exercises:
# ---------
# 1) Rewrite this script to read its data from an external file.
# 2) Rewrite this script to use arrays,
#+ rather than indirect variable referencing.
# Which method is more straightforward and intuitive?
# Which method is easier to code?
# Notes:
# -----
# Shell scripts are inappropriate for anything except the most simple
#+ database applications, and even then it involves workarounds and kludges.
# Much better is to use a language with native support for data structures,
#+ such as C++ or Java (or even Perl).
exit 0
Example 37-4. Using arrays and other miscellaneous trickery to deal four random hands from a deck of cards
#!/bin/bash
# cards.sh
# Deals four random hands from a deck of cards.
UNPICKED=0
PICKED=1
DUPE_CARD=99
LOWER_LIMIT=0
UPPER_LIMIT=51
CARDS_IN_SUIT=13
CARDS=52 declare -a Deck declare -a Suits declare -a Cards
# It would have been easier to implement and more intuitive
#+ with a single, 3-dimensional array.
# Perhaps a future version of Bash will support multidimensional arrays.
initialize_Deck ()
{ i=$LOWER_LIMIT
Chapter 37. Bash, versions 2, 3, and 4 546
Advanced Bash-Scripting Guide until [ "$i" -gt $UPPER_LIMIT ] do
Deck[i]=$UNPICKED # Set each card of "Deck" as unpicked.
let "i += 1" done echo
} initialize_Suits ()
{
Suits[0]=C #Clubs
Suits[1]=D #Diamonds
Suits[2]=H #Hearts
Suits[3]=S #Spades
} initialize_Cards ()
{
Cards=(2 3 4 5 6 7 8 9 10 J Q K A)
# Alternate method of initializing an array.
} pick_a_card ()
{ card_number=$RANDOM let "card_number %= $CARDS" # Restrict range to 0 - 51, i.e., 52 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 "suit_number = number / CARDS_IN_SUIT" suit=${Suits[suit_number]} echo -n "$suit-" let "card_no = number % CARDS_IN_SUIT"
Card=${Cards[card_no]} printf %-4s $Card
# Print cards in neat columns.
} seed_random () # Seed random number generator.
{ # What happens if you don't do this?
seed=`eval date +%s` let "seed %= 32766"
RANDOM=$seed
} # Consider other methods of seeding the random number generator.
deal_cards ()
{ echo cards_picked=0 while [ "$cards_picked" -le $UPPER_LIMIT ] do
pick_a_card
Chapter 37. Bash, versions 2, 3, and 4 547
Stáhnout
Reklama