for 循環與位置參數( $*、$@)

word splitting(分詞)

若是沒有在雙引號中,變量在進行參數擴展、命令替換和算術擴展以後,shell 會對變量進行分詞,好比:html

$ echo a   b  c      d
a b c d

shell 將 $IFS 的每一個字符做爲分隔符,若是 $IFS 是 unset 的,則有默認值 <space><tab><newline>shell

分詞的時候,首先忽略變量首位的空白符 <space><tab><newline>,再分隔獲得單詞。bash

判斷 $IFS 是否 unset 的方法。spa

// 文件test
#!/usr/bin/bash
if [ -v IFS ];then
  echo ==\$IFS=$IFS==
else
  echo ==\$IFS is unset==
fi

$ ./test
==$IFS= ==

for 循環中的 $* 與 $@

$*$@ 都能表示全部的位置參數。code

  • 未在雙引號中:兩者用法一致,都會進行分詞。htm

    // 文件test
    #!/usr/bin/bash
    echo '==$*=='
    for name in $*
    do
    echo $name
    done
    
    echo '==$@=='
    for name in $@
    do
    echo $name
    done
    
    $ ./test a  s  d fff
    ==$*==
    a
    s
    d
    fff
    ==$@==
    a
    s
    d
    fff
  • 在雙引號中:

$* 會先分詞,再以 $IFS 的第一個字符爲分隔符,合併成一個字符串; "$*" 至關於 "$1c$2c…"c 表示 $IFS 的第一個字符。字符串

$@ 也會分詞,但不會合併成一個字符串;
"$@" 至關於 "$1" "$2"…,跟不加雙引號其甩出是同樣的。get

// 文件test
#!/usr/bin/bash
echo '==$*=='
for name in "$*"
do
  echo $name
done

echo '==$@=='
for name in "$@"
do
  echo $name
done

$ ./test a  s  d fff
==$*==
a s d fff
==$@==
a
s
d
fff

參考