`

shell 变量和参数

阅读更多

变量和参数

部分引用[双引号, 即"]. "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 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics