在 Linux Shell 中,$* 和 $@ 都表示参数列表中的所有参数,它们在具体使用中会有哪些不同呢?
先看一下下面的代码:
#!/bin/sh
foo(){ echo $* } bar(){ echo $@ } foo 1 2 3 4 bar 1 2 3 4
执行输出:
1 2 3 4
1 2 3 4
输出没有任何区别,那么$*和$@的区别在哪里?
我们再看一组代码:
#!/bin/bash test_param() { echo "Receive $# parameters" echo Using '$*' echo for param in $*; do printf '==>%s<== ' "$param" done; echo echo Using '"$*"' for param in "$*"; do printf '==>%s<== ' "$param" done; echo echo Using '$@' for param in $@; do printf '==>%s<== ' "$param" done; echo echo Using '"$@"'; for param in "$@"; do printf '==>%s<== ' "$param" done } IFS="^${IFS}" test_param 1 2 3 "a b c"
执行输出:
Receive 4 parameters Using $* ==>1<== ==>2<== ==>3<== ==>a<== ==>b<== ==>c<== Using "$*" ==>1^2^3^a b c<== Using $@ ==>1<== ==>2<== ==>3<== ==>a<== ==>b<== ==>c<== Using "$@" ==>1<== ==>2<== ==>3<== ==>a b c<==
通过上面的代码我们可以看出:
- 当$*和$@没有被引用的时候,它们确实没有什么区别,都会把位置参数当成一个个体。(我们最好不要使用,因为如果位置参数中带有空格或者通配符的情况下,可能结果会和我们想要的不一样)
- "$*" 会把所有位置参数当成一个整体(或者说当成一个单词),如果没有位置参数,则"$*"为空,如果有两个位置参数并且IFS为空格时,"$*"相当于"$1 $2"
- "$@" 会把所有位置参数当成一个单独的字段,如果没有位置参数($#为0),则"$@"展开为空(不是空字符串,而是空列表),如果存在一个位置参数,则"$@"相当于"$1",如果有两个参数,则"$@"相当于"$1" "$2"等等
$*使用举例:
#!/bin/sh join(){ IFS=$1 shift echo "$*" | bc } join $*
[root@localhost ~]# sh join.sh + 1 2 3 4
10