我写了一个简单的脚本,它接受任意数量的参数来证明$@
和$*
之间的差异:
#!/bin/bash
echo "double quoted $* $@"
echo 'single quoted $* $@'
在CLI上我做了
$./stuff.sh a b c d e f dfs
这就是打印出来的
double quoted a b c d e f dfs a b c d e f dfs
single quoted $* $@
因为它们是相同的,这意味着$@
等于$*
?还是有一点我错过了?
答案 0 :(得分:6)
来自Special Parameters in Bash Reference Manual
*
从一个开始扩展到位置参数。当。。。的时候 扩展发生在双引号内,它扩展为单个单词 每个参数的值由第一个字符分隔 IFS特殊变量。也就是说,“$ *”相当于“$ 1c $ 2c ......”, 其中c是IFS变量值的第一个字符。如果 IFS未设置,参数由空格分隔。如果IFS为null, 参数连接时没有插入分隔符。
@
从一个开始扩展到位置参数。当。。。的时候 扩展发生在双引号内,每个参数扩展为a 单词。也就是说,“$ @”相当于“$ 1”“$ 2”....如果 双语扩张发生在一个词内,扩展了 第一个参数与原始的开头部分连接在一起 单词,并将最后一个参数的扩展与最后一个参数连接起来 原始单词的一部分。没有位置参数时 “$ @”和$ @扩展为空(即,它们被移除)。
更好的例子:
$ d=(a b c)
$ for i in "${d[*]}"; do echo $i; done <---- it is a field all together
a b c
$ for i in "${d[@]}"; do echo $i; done <---- each item is a different field
a
b
c
答案 1 :(得分:3)
来自http://linuxsig.org/files/bash_scripting.html:
$ *存储在命令行上输入的所有参数
所以
$1 $2 ...
“$ @”存储在命令行中输入的所有参数,单独引用
所以
"$1" "$2" ...
答案 2 :(得分:3)
$ set -- "hello world" foo bar
$ printf '<%s> ' "$@"; echo
<hello world> <foo> <bar> # "$@" keeps original separation
$ printf '<%s> ' "$*"; echo
<hello world foo bar> # "$*" combines everything into one string
$ printf '<%s> ' $*; echo
<hello> <world> <foo> <bar> # $* (no quotes) loses delimitation entirely.
从技术上讲,$*
不仅限于空格分隔;它使用$IFS
的第一个字符。这有利于您:
jars=( *.jar )
IFS=:
export CLASSPATH=${jars[*]}