Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Advanced Bash Shell Scripting Gude.pdf
Скачиваний:
57
Добавлен:
17.08.2013
Размер:
4.82 Mб
Скачать

Bash, version 2

Advanced Bash-Scripting Guide:

Prev

Next

Chapter 35. Bash, version 2

The current version of Bash, the one you have running on your machine, is actually version 2.XX.Y.

bash$ echo $BASH_VERSION

2.05.8(1)-release

This update of the classic Bash scripting language added array variables, [1] string and parameter expansion, and a better method of indirect variable references, among other features.

Example 35-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' echo $'Three form feeds \f \f \f'

echo $'10 newlines \n\n\n\n\n\n\n\n\n\n'

exit 0

Example 35-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 greatly superior to the old "eval var1=\$$var2"

echo

t=table_cell_3 table_cell_3=24

http://tldp.org/LDP/abs/html/bash2.html (1 of 6) [7/15/2002 6:34:20 PM]

Bash, version 2

echo "t = ${!t}"

# t = 24

table_cell_3=387

 

echo "Value of t changed to ${!t}" # 387

#This is 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 35-3. Simple database application, using indirect variable referencing

#!/bin/bash

#resistor-inventory.sh

#Simple database application using indirect variable referencing.

#============================================================== #

#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=.25

 

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

http://tldp.org/LDP/abs/html/bash2.html (2 of 6) [7/15/2002 6:34:20 PM]

Bash, version 2

echo

echo "Catalog number $catalog_number:"

echo "There are ${!Inv} of [${!Val} ohm / ${!Pdissip} watt] resistors in stock." echo "These are located in bin # ${!Loc}."

echo "Their color code is \"${!Ccode}\"."

break done

echo; echo

#Exercise:

#--------

#Rewrite this script using arrays, rather than indirect variable referencing.

#Which method is more straightforward and intuitive?

#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 35-4. Using arrays and other miscellaneous trickery to deal four random hands from a deck of cards

#!/bin/bash

# May need to be invoked with #!/bin/bash2 on older machines.

#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_SUIT=13

CARDS=52

declare -a Deck declare -a Suits declare -a Cards

#It would have been easier and more intuitive

#with a single, 3-dimensional array.

#Perhaps a future version of Bash will support multidimensional arrays.

initialize_Deck ()

{

http://tldp.org/LDP/abs/html/bash2.html (3 of 6) [7/15/2002 6:34:20 PM]

Bash, version 2

i=$LOWER_LIMIT

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"

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.

{

seed=`eval date +%s` let "seed %= 32766" RANDOM=$seed

}

http://tldp.org/LDP/abs/html/bash2.html (4 of 6) [7/15/2002 6:34:20 PM]

Bash, version 2

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_SUIT"

if [ "$u" -eq 0 ] # Nested if/then condition test. 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_Suits 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 suits.

#You may add other bells and whistles if you like.

http://tldp.org/LDP/abs/html/bash2.html (5 of 6) [7/15/2002 6:34:20 PM]

Bash, version 2

#Exercise 3:

#Simplify and streamline the logic of the script.

Notes

[1]Chet Ramey promises associative arrays (a Perl feature) in a future Bash release.

Prev

Home

Next

Shell Scripting Under Windows

Up

Endnotes

http://tldp.org/LDP/abs/html/bash2.html (6 of 6) [7/15/2002 6:34:20 PM]