天天看點

$* 和$@的差別

1 概述

$* 和$@在有加雙引号和沒有雙引号的情況下有明顯的差別,在這邊用一個實驗進行測試

實驗的環境如下

為了讓實驗結果更加明确,在參數裡多了一個被雙引号引用的參數,而且雙引号内裡也有多個數值,如下

運作語句 ./varnu.sh a b "12 66 a1c" 99

參數為  a b "12 66 a1c" 99

2 實驗

2.1 $* 和 $@沒有雙引号

$* 和 $@ 都表示傳遞給函數或腳本的所有參數,不被雙引号(" ")包含時,都以"$1" "$2" … "$n" 的形式輸出所有參數。

沒有雙引号的話,$* 和 $@都可以把參數看成是清單

此時系統認為$* 和 $@參數都是清單,為 a,  b,  12 66 a1c,  99四個參數,但是通過循環可以看出,其實是進行了6次的移位循環

2.2 "$*" 和 "$@"有雙引号

但是當$* 和 $@被雙引号(" ")包含時,"$*" 會将所有的參數作為一個整體,以"$1 $2 … $n"的形式輸出所有參數;"$@" 會将各個參數分開,以"$1" "$2" … "$n" 的形式輸出所有參數。

但是,如果參數裡本身含有雙引号,而且雙引号裡也有多個數值,如下

加了雙引号的

"$@" 參數是 a , b , 12 66 a1c , 99, 4個參數,是清單,而且隻進行了4位移位循環

"$*"參數是a b "12 66 a1c" 99,就一個參數,不是清單,就當成一行字元串,沒有進行移位循環

2.3 代碼和結果

下面的例子可以清楚的看到 $* 和 $@ 的差別,為了能進行比較,我将四段代碼寫在同一腳本裡,通過對腳本裡shift語句進行注釋。來分别觀察每段腳本的輸出結果,代碼如下

 #!/bin/bash
i=1
echo \$@ is $@
for t in $@;do
echo "$1 is \$1,it $i shift, \$@  is $@ "
let i++
#  shift
done
i=1
echo now  \"\$@\" is "$@"
for t in "$@";do
echo "$1 is \$1,it $i shift, \"\$@\"  is $@ "
let i++
#shift
done
i=1
echo \$* is $*
for t in $*;do
echo "$1 is \$1,it $i shift, \$*  is $* "
let i++
#shift
done
i=1
echo \"\$*\" is "$*"
for t in "$*" ;do
echo "$1 is \$1,it $i shift, \"\$*\"  is $* "
[ -z "$*" ] &&  echo \"\$*\" is null || echo "\"\$*\" is $*"
shift
let i++
done      

得到實驗結果如下圖,一張綜合的對比圖和四張分屏截圖

$* 和$@的差別
$* 和$@的差別
$* 和$@的差別
$* 和$@的差別
$