$@ 和 $* 有什么区别

$@ 和 $* 有什么区别

根据这一页、 $@ 和 $* 做几乎相同的事情:

The $@ holds list of all arguments passed to the script. 
The $* holds list of all arguments passed to the script.

在搜索完谷歌中的所有热门搜索后,我无法找到任何解释为什么会有两个看似重复的语法。

它们在我的脚本中似乎发挥着相同的作用。

cat foo.sh
#!/bin/bash
echo The parameters passed in are $@
echo The parameters passed in are $*

./foo.sh herp derp
The parameters passed in are herp derp
The parameters passed in are herp derp
  1. 其中一个比另一个更受青睐吗?
  2. 为什么有 2 个内置变量可以做完全相同的事情?

其他来源
bash.cyberciti.biz

答案1

他们不一样。 $*是单个字符串,而$@是实际数组。要查看差异,请像这样执行以下脚本:

 > ./test.sh one two "three four"

剧本:

#!/bin/bash

echo "Using \"\$*\":"
for a in "$*"; do
    echo $a;
done

echo -e "\nUsing \$*:"
for a in $*; do
    echo $a;
done

echo -e "\nUsing \"\$@\":"
for a in "$@"; do
    echo $a;
done

echo -e "\nUsing \$@:"
for a in $@; do
    echo $a;
done              

四种情况的解释和结果如下。

第一种情况,参数被视为一个long细绳:

Using "$*":
one two three four

情况 2(不带引号)- 字符串被循环分解为单词for

Using $*:
one
two
three
four

情况 3 - 它将 $@ 的每个元素视为带引号的字符串:

Using "$@":
one
two
three four

最后一种情况 - 它将每个元素视为不带引号的字符串,因此最后一个元素再次被分割为for three four

Using $@:
one
two
three
four

答案2

区别在于它们的扩展方式。

$*扩展为单个参数,所有元素均以空格分隔(实际上是 的第一个字符$IFS)。
$@扩展到多个参数。

例如

#!/bin/bash
echo "With *:"
for arg in "$*"; do echo "<$arg>"; done
echo
echo "With @:"
for arg in "$@"; do echo "<$arg>"; done

 

$ /tmp/test.sh 1  2 "3  4"
With *:
<1 2 3  4>

With @:
<1>
<2>
<3  4>

答案3

您可以查看Bash 初学者指南了解更多信息。它们的作用几乎相同,只是分离方式有所不同:

$*- 扩展到位置参数,从 1 开始。当扩展发生在双引号内时,它会扩展为单个单词,每个参数的值由 IFS 特殊变量的第一个字符分隔。

$@- 扩展到位置参数,从 1 开始。当扩展发生在双引号内时,每个参数都会扩展为一个单独的单词。

但除非您设置IFS为默认值以外的值,否则它可能看起来相同。

答案4

其中一个比另一个更受青睐吗?

一个简短的答案是"$@"

如果您使用它们时不带双引号,则它们是相同的。在这种情况下,没有谁比另一方更受青睐。但我建议您始终使用双引号,除非您知道自己到底想要什么。

为什么有 2 个内置变量可以做完全相同的事情?

$*和之间没有区别$@,但是"$@""$*"has 之间没有区别。

你可以看到我的回答这个帖子看看它们有何不同。

相关内容