在 Linux Shell 中,$* 和 $@ 都表示參數列表中的所有參數,它們在具體使用中會有哪些不同呢?
先看一下下面的代碼:
#!/bin/sh
foo(){ echo $* } bar(){ echo $@ } foo 1 2 3 4 bar 1 2 3 4
執行輸出:
1 2 3 4
1 2 3 4
輸出沒有任何區別,那么$*和$@的區別在哪里?
我們再看一組代碼:
#!/bin/bash test_param() { echo "Receive $# parameters" echo Using '$*' echo for param in $*; do printf '==>%s<==\n' "$param" done; echo echo Using '"$*"' for param in "$*"; do printf '==>%s<==\n' "$param" done; echo echo Using '$@' for param in $@; do printf '==>%s<==\n' "$param" done; echo echo Using '"$@"'; for param in "$@"; do printf '==>%s<==\n' "$param" done } IFS="^${IFS}" test_param 1 2 3 "a b c"
執行輸出:
Receive 4 parameters Using $* ==>1<== ==>2<== ==>3<== ==>a<== ==>b<== ==>c<== Using "$*" ==>1^2^3^a b c<== Using $@ ==>1<== ==>2<== ==>3<== ==>a<== ==>b<== ==>c<== Using "$@" ==>1<== ==>2<== ==>3<== ==>a b c<==
通過上面的代碼我們可以看出:
- 當$*和$@沒有被引用的時候,它們確實沒有什么區別,都會把位置參數當成一個個體。(我們最好不要使用,因為如果位置參數中帶有空格或者通配符的情況下,可能結果會和我們想要的不一樣)
- "$*" 會把所有位置參數當成一個整體(或者說當成一個單詞),如果沒有位置參數,則"$*"為空,如果有兩個位置參數並且IFS為空格時,"$*"相當於"$1 $2"
- "$@" 會把所有位置參數當成一個單獨的字段,如果沒有位置參數($#為0),則"$@"展開為空(不是空字符串,而是空列表),如果存在一個位置參數,則"$@"相當於"$1",如果有兩個參數,則"$@"相當於"$1" "$2"等等
$*使用舉例:
#!/bin/sh join(){ IFS=$1 shift echo "$*" | bc } join $*
[root@localhost ~]# sh join.sh + 1 2 3 4
10
