bash脚本中$ @和$ *之间的差异

时间:2014-01-12 06:27:08

标签: linux bash shell

下面有4个bash片段。我用./script.sh a b c

打电话给他们
for arg in $@; do 
echo "$arg"
done   ## output "a\nb\nc"

for arg in "$@"; do
echo "$arg"
done  ## output "a\nb\nc" -- I don't know why

for arg in $*; do
echo "$arg"
done  ##    output "a\nb\nc"

for arg in "$*"; do
echo "$arg"
done    ## output "abc"

我不知道$@$*之间的确切差异,
我认为"$@""$*"应该相同,但事实并非如此。为什么呢?

3 个答案:

答案 0 :(得分:26)

如果您有脚本foo.sh

asterisk "$*"
at-sign "$@"

并将其命名为:

./foo.sh "a a" "b b" "c c"

它相当于:

asterisk "a a b b c c"
at-sign "a a" "b b" "c c"

没有引号,它们是相同的:

asterisk $*
at-sign $@

相当于:

asterisk "a" "a" "b" "b" "c" "c"
at-sign "a" "a" "b" "b" "c" "c"

答案 1 :(得分:6)

$ *和$ @之间的区别是::

"$*" All the positional parameters (as a single word) *

"$@" All the positional parameters (as separate strings)

如果使用./my_c $ @,将给bash脚本的三个命令行参数传递给C程序,

您获得结果ARG[1] == "par1" ARG[2] == "par2" ARG[3] == "par3"

如果使用./my_c $ *将给bash脚本的三个命令行参数传递给C程序,

您获得结果ARG[1] == "par1 par2 par3"

答案 2 :(得分:1)

这在shell脚本中很重要:例如脚本testargs.sh

#! /bin/bash -p

echo $#

for i in $(seq 1 $#)
do
    echo "$i: ${!i}"
done

for val in "$@"; do
    echo "in quote @, $val"
done

for val in "$*"; do
    echo "in quote *, $val"
done

for val in $@; do
    echo "not in quote @, $val"
done

for val in $*; do
    echo "not in quote *, $val"
done

如果此脚本以/tmp/testargs.sh a b c 'd e'执行, 结果是:

4
1: a
2: b
3: c
4: d e
in quote @, a
in quote @, b
in quote @, c
in quote @, d e
in quote *, a b c d e
not in quote @, a
not in quote @, b
not in quote @, c
not in quote @, d
not in quote @, e
not in quote *, a
not in quote *, b
not in quote *, c
not in quote *, d
not in quote *, e

因此,如果要保留参数的数量,请始终使用“$ @”或使用for i in $(seq 1 $#)循环遍历每个参数。没有引号,两者都是相同的。