访问bash命令行参数$@ vs $*

在许多SO问题和bash教程中,我看到我可以通过两种方式访问bash脚本中的命令行参数:

$ ~ >cat testargs.sh
#!/bin/bash


echo "you passed me" $*
echo "you passed me" $@

结果是:

$ ~> bash testargs.sh arg1 arg2
you passed me arg1 arg2
you passed me arg1 arg2
$*$@有什么区别?< br > 什么时候应该使用前者,什么时候应该使用后者?< / p >
239653 次浏览

$@与$*相同,但每个参数都是一个带引号的字符串,也就是说,参数被完整地传递,没有解释或展开。这意味着,除其他外,参数列表中的每个参数都被视为一个单独的单词。

当然,“$@”应该加引号。

< a href = " http://tldp.org/LDP/abs/html/internalvariables.html ARGLIST " > http://tldp.org/LDP/abs/html/internalvariables.html ARGLIST < / >

$ *

展开到位置参数,从1开始。当 展开发生在双引号内,它展开为单个单词 的第一个字符分隔每个参数的值 IFS特殊变量。也就是说,“$*”相当于“$1c$2c…”, 其中c是IFS变量值的第一个字符。如果 不设置IFS,参数间以空格分隔。如果IFS为空, 参数之间没有分隔符进行连接

$ @

展开到位置参数,从1开始。当 展开发生在双引号内,每个参数展开为a 单独的词。也就是说,“$@”相当于“$1”“$2”…如果 双引号展开出现在一个词内,展开的 第一个参数与原始参数的开始部分连接 Word,最后一个参数的展开与最后一个参数连接 原来单词的一部分。当没有位置参数时, "$@"和$@展开为空(即,它们被删除)

来源:Bash的男人

当特殊参数被引用时,会出现差异。让我来说明一下它们的区别:

$ set -- "arg  1" "arg  2" "arg  3"


$ for word in $*; do echo "$word"; done
arg
1
arg
2
arg
3


$ for word in $@; do echo "$word"; done
arg
1
arg
2
arg
3


$ for word in "$*"; do echo "$word"; done
arg  1 arg  2 arg  3


$ for word in "$@"; do echo "$word"; done
arg  1
arg  2
arg  3

关于引用重要性的另一个例子:注意在“arg”和数字之间有2个空格,但如果我没有引用$word:

$ for word in "$@"; do echo $word; done
arg 1
arg 2
arg 3

在bash中,"$@"是迭代的“默认”列表:

$ for word; do echo "$word"; done
arg  1
arg  2
arg  3

一个来自Bash黑客维基的非常方便的概览表:

< span style=" font - family:宋体;"> < / th >语法 < span style=" font - family:宋体;"> < / th >有效的结果 < span style=" font - family:宋体;"> $* td > < / < span style=" font - family:宋体;"> $1 $2 $3 … ${N} td > < / < span style=" font - family:宋体;"> $@ td > < / < span style=" font - family:宋体;"> $1 $2 $3 … ${N} td > < / < span style=" font - family:宋体;"> "$*" td > < / < span style=" font - family:宋体;"> "$1c$2c$3c…c${N}" td > < / < span style=" font - family:宋体;"> "$@" td > < / < span style=" font - family:宋体;"> "$1" "$2" "$3" … "${N}" td > < /

其中第三行中的c是shell变量输入字段分隔符的第一个字符。

如果要存储实参,则在数组变量中加载它们.;

这个例子让我们在使用“at”和“asterix”时突出显示它们之间的区别。 我声明了两个数组"fruits"和"vegetables"

fruits=(apple pear plumm peach melon)
vegetables=(carrot tomato cucumber potatoe onion)


printf "Fruits:\t%s\n" "${fruits[*]}"
printf "Fruits:\t%s\n" "${fruits[@]}"
echo + --------------------------------------------- +
printf "Vegetables:\t%s\n" "${vegetables[*]}"
printf "Vegetables:\t%s\n" "${vegetables[@]}"

请看上面代码的结果:

Fruits: apple pear plumm peach melon
Fruits: apple
Fruits: pear
Fruits: plumm
Fruits: peach
Fruits: melon
+ --------------------------------------------- +
Vegetables: carrot tomato cucumber potatoe onion
Vegetables: carrot
Vegetables: tomato
Vegetables: cucumber
Vegetables: potatoe
Vegetables: onion