苏泊尔电压力锅的食谱:Shell 中大括号(curly brackets)的含义
来源:百度文库 编辑:九乡新闻网 时间:2024/04/29 06:05:24
Arrays
The Korn shell and Bash provide alimited array capability (arrays are not a part of the POSIX standard shell).Bash arrays may contain an unlimited number of elements (subject to memorylimitations); Korn shell arrays are limited to 4096 elements. Array indexing inboth shells starts at zero. An array element is accessed with a subscript, which is an integer-valued expressionenclosed inside a pair of brackets. You don't declare the maximum size of ashell array; you simply assign values to elements as you need them. The valuesthat you can assign are the same as for ordinary variables.
$ arr[O]=hello
$ arr[1]="some text"
$ arr[2]=/users/steve/memos
$
To retrieve an element from an array, you write the array namefollowed by the element number, enclosed inside a pair of brackets as before.The entire construct must be enclosed inside a pair of curly braces, which isthen preceded by a dollar sign.
$ echo ${array[0]}
hello
$ echo ${array[1]}
some text
$ echo ${array[2]}
/users/steve/memos
$ echo $array
hello
$
As you can see from the preceding example, if no subscript isspecified, element zero is used.
If you forget the curly braces when performing thesubstitution, here's what happens:
$ echo $array[1]
hello[1]
$
In the preceding example, the value of array issubstituted (hello—the value inside array[0]) and thenechoed along with [1]. (Note that because the shell doesfilename substitution after variable substitution, the shell would attempt tomatch the pattern hello[1] against the files in your currentdirectory.)
The construct [*] can be usedas a subscript to substitute all the elements of the array on the command line,with each element delimited by a single space character.
$ echo ${array[*]}
hello some text /users/steve/memos
$
The construct ${#array[*]} can be used to substitute the numberof elements in the array array.
$ echo ${#array[*]}
3
$
Note that the number reported here is the actual number ofvalues stored inside the array, not the largest subscript used to store anelement inside the array.
$ array[10]=foo
$ echo ${array[*]} Display all elements
hello some text /users/steve/memos foo
$ echo ${#array[*]} Number of elements
4
$
You can declare an array of integers to the shell simply bygiving the array name to typeset -i:
typeset -i data
Integer calculations can be performed on array elements usingthe ((...)) construct:
$ typeset -i array
$ array[0]=100
$ array[1]=50
$ (( array[2] = array[0] + array[1] ))
$ echo ${array[2]}
150
$ i=1
$ echo ${array[i]}
50
$ array[3]=array[0]+array[2]
$ echo ${array[3]}
250
$
Note that not only can you omit the dollar signs and the curlybraces when referencing array elements inside double parentheses, you also canomit them outside when the array is declared to be of integer type. Also notethat dollar signs are not needed before variables used in subscriptexpressions.
The following program, called reverse, reads in up to4096 lines from standard input and then writes them back out to standard outputin reverse order:
$ cat reverse
# read lines to array buf
typeset -i line=0
while (( line < 4096 )) && read buf[line]
do
(( line = line + 1 ))
done
# now print the lines in reverse order
while (( line > 0 )) do
(( line = line - 1 ))
echo "${buf[line]}"
done
$ reverse
line one
line two
line three
Ctrl+d
line three
line two
line one
$
The first while loop executes as long as 4096 or fewerlines have been read and there is more data to be read from standard input(recall the && described at the end of Chapter 8, "Decisions, Decisions").
The following function, cdh, changes the current directory like cdbut uses an array to keep a history of previous directories. It allows the userto list the directory history and change back to any directory in it:
$ cat cdh
CDHIST[0]=$PWD # initialize CDHIST[0]
cdh ()
{
typeset –i cdlen i
if [ $# -eq 0 ] # default to HOME with no arguments
then
set -- $HOME
fi
cdlen=${#CDHIST[*]} # number of elements in CDHIST
case "$@" in
-l) # print directory list
i=0
while ((i < cdlen))
do
printf "%3d %s\n" $i ${CDHIST[i]}
((i = i + 1))
done
return ;;
-[0-9]|-[0-9][0-9]) # cd to dir in list
i=${1#-} # remove leading '-'
cd ${CDHIST[i]} ;;
*) # cd to new dir
cd $@ ;;
esac
CDHIST[cdlen]=$PWD
}
$
The CDHIST array stores each directory visited bycdh, and the first element, CDHIST[0], is initialized with thecurrent directory when the cdh file is run:
$ pwd
/users/pat
$ . cdh Define cdh function
$ cdh /tmp
$ cdh –l
0 /users/pat
1 /tmp
$
When the cdh file was run, CDHIST[0] wasassigned /users/pat, and the cdh function was defined; whencdh /tmp was executed, cdlen was assigned the number ofelements in CDHIST (one), and CDHIST[1] was assigned/tmp. The cdh –l caused printf to display eachelement of CDHIST (on this invocation, cdlen was set to 2,because elements 0 and 1 of CDHIST contained data).
Note that the if statement at the beginning of thefunction sets $1 to $HOME if no arguments are passed. Let'stry that out:
$ cdh
$ pwd
/users/pat
$ cdh –l
0 /users/pat
1 /tmp
2 /users/pat
$
Well, it worked, but now /users/pat shows up twice inthe list. One of the exercises at the end of this chapter asks you to remedythis.
Okay, the most useful feature of cdh is the–n option, which causes it to change thecurrent directory to the one specified in the list:
$ cdh /usr/spool/uucppublic
$ cdh –l
0 /users/pat
1 /tmp
2 /users/pat
3 /usr/spool/uucppublic
$ cdh –1
$ pwd
/tmp
$ cdh –3
$ pwd
/usr/spool/uucppublic
$
We can make cdh replace our cd command byusing the fact that alias lookup is performed before built-in commands areexecuted. So if we create a cd alias to cdh, we can have anenhanced cd. In that case, we have to quote every use of cd inthe cdh function to prevent recursion:
$ cat cdh
CDHIST[0]=$PWD # initialize CDHIST[0]
alias cd=cdh
cdh ()
{
typeset –i cdlen i
if [ $# -eq 0 ] # default to HOME with no arguments
then
set -- $HOME
fi
cdlen=${#CDHIST[*]} # number of elements in CDHIST
case "$@" in
-l) # print directory list
i=0
while ((i < cdlen))
do
printf "%3d %s\n" $i ${CDHIST[i]}
((i = i + 1))
done
return ;;
-[0-9]|-[0-9][0-9]) # cd to dir in list
i=${1#-} # remove leading '-'
'cd' ${CDHIST[i]} ;;
*) # cd to new dir
'cd' $@ ;;
esac
CDHIST[cdlen]=$PWD
}
$ . cdh Define cdh function and cd alias
$ cd /tmp
$ cd –l
0 /users/pat
1 /tmp
$ cd /usr/spool
$ cd –l
0 /users/pat
1 /tmp
2 /usr/spool
$
Table 15.3 summarizesthe various array constructs in the Korn shell and Bash.
Table 15.3. Array Constructs
Construct
Meaning
${array[i]}
Substitute value of element i
$array
Substitute value of first element (array[0])
${array[*]}
Substitute value of all elements
${#array[*]}
Substitute number of elements
array[i]=val
Store val into array[i]