变量和参数
部分引用[双引号, 即"]. "STRING"将会阻止(解释)STRING中大部分特殊的字符.
1 COMMAND $variable2 $variable2 $variable2 # COMMAND将不带参数执行.
2 COMMAND "$variable2" "$variable2" "$variable2" # COMMAND将以3个空参数来执行.
3 COMMAND "$variable2 $variable2 $variable2" # COMMAND将以1个参数来执行(2空格)
全引用[单引号, 即’]. ’STRING’将会阻止STRING中所有特殊字符的解释. 这是一种比使用"更强烈的形
单引号(’ ’)操作与双引号基本一样, 但是不允许引用变量, 因为$的特殊意义被关闭了. 在单引号中, 任何特殊字符都按照字面的意思进行解释, 除了’. 所以说单引号("全引用")是一种比双引号("部分引用")更严格的引用方法
比较操作符在双中括号对和单中括号对中的行为是不同的. 1 [[ $a == z* ]] # 如果$a以"z"开头(模式匹配)那么结果将为真
2 [[ $a == "z*" ]] # 如果$a与z*相等(就是字面意思完全一样), 那么结果为真.
3
4 [ $a == z* ] # 文件扩展匹配(file globbing)和单词分割有效.
5 [ "$a" == "z*" ] # 如果$a与z*相等(就是字面意思完全一样), 那么结果为真.
6
$*, $@
位置参数.
$?
退出状态码变量. $? 变量 保存了一个命令, 一个函数, 或者是脚本本身的退出状态码.
$$
进程ID变量. 这个$$ 变量 保存了它所在脚本的进程 ID [1]
()
命令组. 1 (a=hello; echo $a)
$0, $1, $2, 等等.
位置参数, 从命令行传递到脚本, 或者传递给函数, 或者set给变量(参见例子 4-5和例子 11-15)
$#
命令行参数 [2] 或者位置参数的个数(参见例子 33-2)
$*
所有的位置参数都被看作为一个单词.
"$*"必须被引用起来.
$@
与$*相同, 但是每个参数都是一个独立的引用字符串, 这就意味着, 参数是被完整传递的, 并没有被解释或扩展. 这也意味着, 参数列表中每个参数都被看作为单独的单词.
当然, "$@"应该被引用起来.
--------------------------------------------------------------------------------
例子 Array-6. arglist: 通过$*和$@列出所有的参数
1 #!/bin/bash
2 # arglist.sh
3 # 多使用几个参数来调用这个脚本, 比如"one two three".
4
5 E_BADARGS=65
6
7 if [ ! -n "$1" ]
8 then
Array echo "Usage: `basename $0` argument1 argument2 etc."
10 exit $E_BADARGS
11 fi
12
13 echo
14
15 index=1 # 起始计数.
16
17 echo "Listing args with \"\$*\":"
18 for arg in "$*" # 如果"$*"不被""引用,那么将不能正常地工作.
1Array do
20 echo "Arg #$index = $arg"
21 let "index+=1"
22 done # $* 将所有的参数看成一个单词.
23 echo "Entire arg list seen as single word."
24
25 echo
26
27 index=1 # 重置计数(译者注: 从1开始).
28 # 如果你写这句会发生什么?
2Array
30 echo "Listing args with \"\$@\":"
31 for arg in "$@"
32 do
33 echo "Arg #$index = $arg"
34 let "index+=1"
35 done # $@ 把每个参数都看成是单独的单词.
36 echo "Arg list seen as separate words."
37
38 echo
3Array
40 index=1 # 重置计数(译者注: 从1开始).
41
42 echo "Listing args with \$* (unquoted):"
43 for arg in $*
44 do
45 echo "Arg #$index = $arg"
46 let "index+=1"
47 done # 未引用的$*将会把参数看成单独的单词.
48 echo "Arg list seen as separate words."
4Array
50 exit 0
--------------------------------------------------------------------------------
shift命令执行以后, $@将会保存命令行中剩余的参数, 但是没有之前的$1, 因为被丢弃了. 1 #!/bin/bash
2 # 使用 ./scriptname 1 2 3 4 5 来调用这个脚本
3
4 echo "$@" # 1 2 3 4 5
5 shift
6 echo "$@" # 2 3 4 5
7 shift
8 echo "$@" # 3 4 5
Array
10 # 每次"shift"都会丢弃$1.
11 # "$@" 将包含剩下的参数.
$@也可以作为工具使用, 用来过滤传递给脚本的输入. cat "$@"结构既可以接受从stdin传递给脚本的输入, 也可以接受从参数中指定的文件中传递给脚本的输入. 参见例子 12-21和例子 12-22 .
$*和$@中的参数有时候会表现出不一致而且令人迷惑的行为, 这都依赖于$IFS的设置.
--------------------------------------------------------------------------------
例子 Array-7. $*和$@的不一致的行为
1 #!/bin/bash
2
3 # 内部Bash变量"$*"和"$@"的古怪行为,
4 #+ 都依赖于它们是否被双引号引用起来.
5 # 单词拆分与换行的不一致的处理.
6
7
8 set -- "First one" "second" "third:one" "" "Fifth: :one"
Array # 设置这个脚本的参数, $1, $2, 等等.
10
11 echo
12
13 echo ’IFS unchanged, using "$*"’
14 c=0
15 for i in "$*" # 引用起来
16 do echo "$((c+=1)): [$i]" # 这行在下边每个例子中都一样.
17 # 打印参数.
18 done
1Array echo ---
20
21 echo ’IFS unchanged, using $*’
22 c=0
23 for i in $* # 未引用
24 do echo "$((c+=1)): [$i]"
25 done
26 echo ---
27
28 echo ’IFS unchanged, using "
[email=$@"’]$@"’[/email]
2Array c=0
30 for i in "$@"
31 do echo "$((c+=1)): [$i]"
32 done
33 echo ---
34
35 echo ’IFS unchanged, using
[email=$@’]$@’[/email]
36 c=0
37 for i in $@
38 do echo "$((c+=1)): [$i]"
3Array done
40 echo ---
41
42 IFS=:
43 echo ’IFS=":", using "$*"’
44 c=0
45 for i in "$*"
46 do echo "$((c+=1)): [$i]"
47 done
48 echo ---
4Array
50 echo ’IFS=":", using $*’
51 c=0
52 for i in $*
53 do echo "$((c+=1)): [$i]"
54 done
55 echo ---
56
57 var=$*
58 echo ’IFS=":", using "$var" (var=$*)’
5Array c=0
60 for i in "$var"
61 do echo "$((c+=1)): [$i]"
62 done
63 echo ---
64
65 echo ’IFS=":", using $var (var=$*)’
66 c=0
67 for i in $var
68 do echo "$((c+=1)): [$i]"
6Array done
70 echo ---
71
72 var="$*"
73 echo ’IFS=":", using $var (var="$*")’
74 c=0
75 for i in $var
76 do echo "$((c+=1)): [$i]"
77 done
78 echo ---
7Array
80 echo ’IFS=":", using "$var" (var="$*")’
81 c=0
82 for i in "$var"
83 do echo "$((c+=1)): [$i]"
84 done
85 echo ---
86
87 echo ’IFS=":", using "
[email=$@"’]$@"’[/email]
88 c=0
8Array for i in "$@"
Array0 do echo "$((c+=1)): [$i]"
Array1 done
Array2 echo ---
Array3
Array4 echo ’IFS=":", using
[email=$@’]$@’[/email]
Array5 c=0
Array6 for i in $@
Array7 do echo "$((c+=1)): [$i]"
Array8 done
ArrayArray echo ---
100
101 var=$@
102 echo ’IFS=":", using $var (
[email=var=$@)’]var=$@)’[/email]
103 c=0
104 for i in $var
105 do echo "$((c+=1)): [$i]"
106 done
107 echo ---
108
10Array echo ’IFS=":", using "$var" (
[email=var=$@)’]var=$@)’[/email]
110 c=0
111 for i in "$var"
112 do echo "$((c+=1)): [$i]"
113 done
114 echo ---
115
116 var="$@"
117 echo ’IFS=":", using "$var" (var="
[email=$@")’]$@")’[/email]
118 c=0
11Array for i in "$var"
120 do echo "$((c+=1)): [$i]"
121 done
122 echo ---
123
124 echo ’IFS=":", using $var (var="
[email=$@")’]$@")’[/email]
125 c=0
126 for i in $var
127 do echo "$((c+=1)): [$i]"
128 done
12Array
130 echo
131
132 # 使用ksh或者zsh -y来试试这个脚本.
133
134 exit 0
135
136 # 这个例子脚本是由Stephane Chazelas所编写,
137 # 并且本书作者做了轻微改动.
--------------------------------------------------------------------------------
$@与$*中的参数只有在被双引号引用起来的时候才会不同.
--------------------------------------------------------------------------------
例子 Array-8. 当$IFS为空时的$*和$@
1 #!/bin/bash
2
3 # 如果$IFS被设置, 但其值为空,
4 #+ 那么"$*"和"$@"将不会像期望的那样显示位置参数.
5
6 mecho () # 打印位置参数.
7 {
8 echo "$1,$2,$3";
Array }
10
11
12 IFS="" # 设置了, 但值为空.
13 set a b c # 位置参数.
14
15 mecho "$*" # abc,,
16 mecho $* # a,b,c
17
18 mecho $@ # a,b,c
1Array mecho "$@" # a,b,c
20
21 # 当$IFS值为空时, $*和$@的行为依赖于
22 #+ 正在运行的Bash或者sh的版本.
23 # 因此在脚本中使用这种"特性"是不明智的.
24
25
26 # 感谢, Stephane Chazelas.
27
28 exit 0
shell 变量和参数
最新推荐文章于 2024-04-26 11:01:12 发布