$@ 和 $* 有什麼區別

$@ 和 $* 有什麼區別

根據這一頁、 $@ 和 $* 做幾乎相同的事情:

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 之間沒有區別。

你可以看到我的回答這個帖子看看它們有何不同。

相關內容