访问bash命令行args $ @ vs $ *

时间:2012-09-07 08:28:47

标签: bash command-line-arguments

在许多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

$*$@之间的区别是什么? 应该何时使用前者,何时使用后者?

5 个答案:

答案 0 :(得分:354)

引用特殊参数时会出现差异。让我来说明不同之处:

$ 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

答案 1 :(得分:196)

Bash Hackers Wiki

中一个非常方便的概述表

$* versus $@ table

其中第三行中的c$IFS的第一个字符,即内部字段分隔符,一个shell变量。

如果要将参数存储在脚本变量中并且参数应包含空格,我全心全意地建议使用"$*" trick with the internal field separator $IFS set to tab

答案 2 :(得分:39)

<强> $ *

  

从一个开始扩展到位置参数。当。。。的时候   扩展发生在双引号内,它扩展为单个单词   每个参数的值由第一个字符分隔   IFS特殊变量。也就是说,“$ *”相当于“$ 1c $ 2c ......”,   其中c是IFS变量值的第一个字符。如果   IFS未设置,参数由空格分隔。如果IFS为null,   参数连接时没有插入分隔符。

<强> $ @

  

从一个开始扩展到位置参数。当。。。的时候   扩展发生在双引号内,每个参数扩展为a   单词。也就是说,“$ @”相当于“$ 1”“$ 2”......如果是   双语扩张发生在一个词内,扩展了   第一个参数与原始的开头部分连接在一起   单词,并将最后一个参数的扩展与最后一个参数连接起来   原始单词的一部分。没有位置参数时   “$ @”和$ @扩展为空(即,它们被移除)。

来源:Bash man

答案 3 :(得分:15)

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

当然,应该引用“$ @”。

http://tldp.org/LDP/abs/html/internalvariables.html#ARGLIST

答案 4 :(得分:1)

在此示例中,我们可能会突出显示使用它们时“ at”和“ asterix”之间的区别。 我声明了两个数组“水果”和“蔬菜”

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