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

得到实验结果如下图,一张综合的对比图和四张分屏截图

1240


1240


1240


1240


1240