多くのSO質問やbashチュートリアルで、bashスクリプトのコマンドライン引数に2つの方法でアクセスできることがわかりました。
$ ~ >cat testargs.sh
#!/bin/bash
echo "you passed me" $*
echo "you passed me" $@
結果は次のとおりです。
$ ~> bash testargs.sh arg1 arg2
you passed me arg1 arg2
you passed me arg1 arg2
$*
と$@
の違いは何ですか?
前者はいつ使うべきで、後者はいつ使うべきですか。
特別なパラメータを引用符で囲むと、違いが現れます。違いを説明しましょう。
$ set -- "arg 1" "arg 2" "arg 3"
$ for Word in $*; do echo "$Word"; done
arg
1
arg
2
arg
3
$ for Word in $@; do echo "$Word"; done
arg
1
arg
2
arg
3
$ for Word in "$*"; do echo "$Word"; done
arg 1 arg 2 arg 3
$ for Word in "$@"; do echo "$Word"; done
arg 1
arg 2
arg 3
引用の重要性に関するもう1つの例: "arg"と数の間には2つのスペースがありますが、$ Wordの引用に失敗した場合は、次のようにします。
$ for Word in "$@"; do echo $Word; done
arg 1
arg 2
arg 3
そしてbashでは、"$@"
が繰り返し処理される "デフォルト"リストです。
$ for Word; do echo "$Word"; done
arg 1
arg 2
arg 3
Bash Hackers Wikiからの便利で便利な概要表 :
3行目のc
は、$IFS
の最初の文字、内部フィールド区切り文字、シェル変数です。
引数をスクリプト変数に格納し、引数にスペースが含まれると予想される場合は、 "$*"
トリックを使用することを心からお勧めします。内部フィールドセパレータ$IFS
はタブに設定されます 。
$ *
位置パラメータを1から始めて展開します。二重引用符内で展開が行われると、各パラメータの値がIFS特殊変数の最初の文字で区切られた単一のWordに展開されます。つまり、 "$ *"は "$ 1c $ 2c ..."と同じです。ここで、cはIFS変数の値の最初の文字です。 IFSが設定されていない場合、パラメーターはスペースで区切られます。 IFSがnullの場合、パラメータは区切り文字なしで結合されます。
$ @
位置パラメータを1から始めて展開します。二重引用符内で展開が行われると、各パラメータは別々のWordに展開されます。つまり、 "$ @"は "$ 1" "$ 2"と同じです。Word内で二重引用符で囲まれた展開が行われた場合、最初のパラメータの展開は元のWordの先頭部分と結合されます。最後のパラメータの最後の部分は、元のWordの最後の部分と結合されています。位置パラメータがない場合、 "$ @"と$ @は、何も展開されません(つまり、削除されます)。
出典: バッシュマン
$ @は$ *と同じですが、各パラメータは引用符で囲まれた文字列です。つまり、パラメータは解釈や展開なしでそのまま渡されます。これは、とりわけ、引数リスト内の各パラメータが別々のWordと見なされることを意味します。
もちろん、 "$ @"は引用符で囲む必要があります。
この例では、atとasterixの違いを強調してみましょう。私は2つの配列を "フルーツ"と "野菜"と宣言しました
fruits=(Apple pear plumm Peach melon)
vegetables=(carrot tomato cucumber potatoe onion)
printf "Fruits:\t%s\n" "${fruits[*]}"
printf "Fruits:\t%s\n" "${fruits[@]}"
echo + --------------------------------------------- +
printf "Vegetables:\t%s\n" "${vegetables[*]}"
printf "Vegetables:\t%s\n" "${vegetables[@]}"
上記のコードの次の結果を参照してください。
Fruits: Apple pear plumm Peach melon
Fruits: Apple
Fruits: pear
Fruits: plumm
Fruits: Peach
Fruits: melon
+ --------------------------------------------- +
Vegetables: carrot tomato cucumber potatoe onion
Vegetables: carrot
Vegetables: tomato
Vegetables: cucumber
Vegetables: potatoe
Vegetables: onion