1 概述
$* 和$@在有加双引号和没有双引号的情况下有明显的区别,在这边用一个实验进行测试
实验的环境如下
为了让实验结果更加明确,在参数里多了一个被双引号引用的参数,而且双引号内里也有多个数值,如下
运行语句 ./varnu.sh a b "12 66 a1c" 99
参数为 a b "12 66 a1c" 99
2 实验
2.1 $* 和 $@没有双引号
$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。
没有双引号的话,$* 和 $@都可以把参数看成是列表
此时系统认为$* 和 $@参数都是列表,为 a, b, 12 66 a1c, 99四个参数,但是通过循环可以看出,其实是进行了6次的移位循环
2.2 "$*" 和 "$@"有双引号
但是当$* 和 $@被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
但是,如果参数里本身含有双引号,而且双引号里也有多个数值,如下
参数为 a b "12 66 a1c" 99
运行语句 ./varnu.sh a b "12 66 a1c" 99
加了双引号的
"$@" 参数是 a , b , 12 66 a1c , 99, 4个参数,是列表,而且只进行了4位移位循环
"$*"参数是a b "12 66 a1c" 99,就一个参数,不是列表,就当成一行字符串,没有进行移位循环
2.3 代码和结果
下面的例子可以清楚的看到 $* 和 $@ 的区别,为了能进行比较,我将四段代码写在同一脚本里,通过对脚本里shift语句进行注释。来分别观察每段脚本的输出结果,代码如下
#!/bin/bash
i=1
echo \$@ is $@
for t in $@;do
echo "$1 is \$1,it $i shift, \$@ is $@ "
let i++
# shift
done
i=1
echo now \"\$@\" is "$@"
for t in "$@";do
echo "$1 is \$1,it $i shift, \"\$@\" is $@ "
let i++
#shift
done
i=1
echo \$* is $*
for t in $*;do
echo "$1 is \$1,it $i shift, \$* is $* "
let i++
#shift
done
i=1
echo \"\$*\" is "$*"
for t in "$*" ;do
echo "$1 is \$1,it $i shift, \"\$*\" is $* "
[ -z "$*" ] && echo \"\$*\" is null || echo "\"\$*\" is $*"
shift
let i++
done
得到的实验结果如下图