在我看来,它们都存储了所有的命令行参数。
那么这两者之间有区别吗?
在我看来,它们都存储了所有的命令行参数。
那么这两者之间有区别吗?
区别微妙;"$*"
将创建一个由$IFS
变量分隔的参数,而"$@"
会扩展为单独的参数。例如,请考虑:
for i in "$@"; do echo "@ '$i'"; done
for i in "$*"; do echo "* '$i'"; done
在使用多个参数运行时:
./testvar foo bar baz 'long arg'
@ 'foo'
@ 'bar'
@ 'baz'
@ 'long arg'
* 'foo bar baz long arg'
更多细节请参考:
http://www.gnu.org/software/bash/manual/bashref.html#Special-Parameters
$*
将位置参数展开,从一开始。当在双引号中进行扩展时,它会展开为一个单词,其中每个参数的值由IFS特殊变量的第一个字符分隔。也就是说,"$*"
等同于 "$1c$2c..."
,其中 c 是 IFS 变量值的第一个字符。如果未设置 IFS,则参数由空格分隔。如果 IFS 为空,则参数连接而成而不使用分隔符。
$@
将位置参数展开,从一开始。当在双引号中进行扩展时,每个参数都会扩展为一个单独的单词。也就是说,"$@"
等同于 "$1" "$2" ....
如果双引号扩展出现在一个单词中,则第一个参数的扩展与原始单词的前部分连接,最后一个参数的扩展与原始单词的后部分连接。 当没有位置参数时,"$@"
和 $@
扩展为空(即它们被删除)。
我个人认为一个关键的区别在于"$@"
保留了原始参数的数量。这是唯一一个能够做到这一点的形式。
例如,如果文件 my_script 包含:
#!/bin/bash
main()
{
echo 'MAIN sees ' $# ' args'
}
main $*
main $@
main "$*"
main "$@"
### end ###
我这样运行它:
my_script 'a b c' d e
我将得到以下输出:MAIN sees 5 args
MAIN sees 5 args
MAIN sees 1 args
MAIN sees 3 args