Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Cooper M.Advanced bash-scripting guide.2002.pdf
Скачиваний:
13
Добавлен:
23.08.2013
Размер:
916.67 Кб
Скачать

 

Advanced Bash−Scripting Guide

 

# NO REPLACEMENT.

v4=${v0/%123/000}

# Matches, but not at end.

echo "v4 = $v4"

# abc1234zip1234abc

 

# NO REPLACEMENT.

exit 0

${!varprefix*}, ${!varprefix@}

Matches all previously declared variables beginning with varprefix.

xyz23=whatever

xyz24=

a=${!xyz*}

# Expands to names of declared variables beginning with "xyz".

echo "a = $a"

# a =

xyz23

xyz24

a=${!xyz@}

# Same as above.

echo "a = $a"

# a =

xyz23

xyz24

#Bash, version 2.04, adds this feature.

9.4.Typing variables: declare or typeset

The declare or typeset builtins (they are exact synonyms) permit restricting the properties of variables. This is a very weak form of the typing available in certain programming languages. The declare command is specific to version 2 or later of Bash. The typeset command also works in ksh scripts.

declare/typeset options

−r readonly

declare −r var1

(declare −r var1 works the same as readonly var1)

This is the rough equivalent of the C const type qualifier. An attempt to change the value of a readonly variable fails with an error message.

−i integer

declare −i number

# The script will treat subsequent occurrences of "number" as an integer.

number=3

 

echo "number = $number"

# number = 3

number=three

echo "number = $number" # number = 0

# Tries to evaluate "three" as an integer.

Note that certain arithmetic operations are permitted for declared integer variables without the need for expr or let.

−a array

declare −a indices

9.4. Typing variables: declare or typeset

88

Advanced Bash−Scripting Guide

The variable indices will be treated as an array.

−f functions

declare −f

A declare −f line with no arguments in a script causes a listing of all the functions previously defined in that script.

declare −f function_name

A declare −f function_name in a script lists just the function named.

−x export

declare −x var3

This declares a variable as available for exporting outside the environment of the script itself.

var=$value

declare −x var3=373

The declare command permits assigning a value to a variable in the same statement as setting its properties.

Example 9−17. Using declare to type variables

#!/bin/bash

func1 ()

{

echo This is a function.

}

declare −f

# Lists the function above.

echo

 

 

declare −i var1

# var1 is an integer.

var1=2367

 

 

echo "var1 declared as $var1"

 

var1=var1+1

# Integer declaration eliminates the need for 'let'.

echo "var1 incremented by 1 is $var1."

# Attempt to change variable declared as integer

echo "Attempting to change var1 to floating point value, 2367.1."

var1=2367.1

# Results in error message, with no change to variable.

echo "var1 is still $var1"

 

echo

 

 

declare −r var2=13.36

# 'declare' permits setting a variable property

 

 

#+ and simultaneously assigning it a value.

echo "var2 declared as $var2" # Attempt to change readonly variable.

var2=13.37

 

# Generates error message, and exit from script.

9.4. Typing variables: declare or typeset

89

Advanced Bash−Scripting Guide

echo "var2 is still $var2" # This line will not execute.

exit 0

# Script will not exit here.

 

 

9.5. Indirect References to Variables

Assume that the value of a variable is the name of a second variable. Is it somehow possible to retrieve the value of this second variable from the first one? For example, if a=letter_of_alphabet and letter_of_alphabet=z, can a reference to a return z? This can indeed be done, and it is called an indirect reference. It uses the unusual eval var1=\$$var2 notation.

Example 9−18. Indirect References

#!/bin/bash

# Indirect variable referencing.

a=letter_of_alphabet letter_of_alphabet=z

echo

#Direct reference. echo "a = $a"

#Indirect reference. eval a=\$$a

echo "Now a = $a"

echo

# Now, let's try changing the second order reference.

t=table_cell_3 table_cell_3=24

echo "\"table_cell_3\" = $table_cell_3"

echo −n "dereferenced \"t\" = "; eval echo \$$t

#In this simple case,

#eval t=\$$t; echo "\"t\" = $t"

#also works (why?).

echo

t=table_cell_3 NEW_VAL=387 table_cell_3=$NEW_VAL

echo "Changing value of \"table_cell_3\" to $NEW_VAL." echo "\"table_cell_3\" now $table_cell_3"

echo −n "dereferenced \"t\" now "; eval echo \$$t

#"eval" takes the two arguments "echo" and "\$$t" (set equal to $table_cell_3) echo

#(Thanks, S.C., for clearing up the above behavior.)

9.5. Indirect References to Variables

90

Advanced Bash−Scripting Guide

#Another method is the ${!t} notation, discussed in "Bash, version 2" section.

#See also example "ex78.sh".

exit 0

Example 9−19. Passing an indirect reference to awk

#!/bin/bash

#Another version of the "column totaler" script

#that adds up a specified column (of numbers) in the target file.

#This uses indirect references.

ARGS=2

E_WRONGARGS=65

if [ $# −ne "$ARGS" ] # Check for proper no. of command line args. then

echo "Usage: `basename $0` filename column−number" exit $E_WRONGARGS

fi

filename=$1 column_number=$2

#===== Same as original script, up to this point =====#

# A multi−line awk script is invoked by awk ' ..... '

#Begin awk script.

#−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

awk "

{ total += \$${column_number} # indirect reference

}

END {

print total

}

""$filename"

#−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

#End awk script.

#Indirect variable reference avoids the hassles

#of referencing a shell variable within the embedded awk script.

#Thanks, Stephane Chazelas.

exit 0

This method of indirect referencing is a bit tricky. If the second order variable changes its value, then the the first order variable must be properly dereferenced (as in the above example). Fortunately, the ${!variable} notation introduced with version 2 of Bash (see Example 35−2) makes

9.5. Indirect References to Variables

91