どちらもすべてのコマンドライン引数を保存しているように思えます。
では、両者に違いはありますか?
違いは微妙です。変数で"$*"
区切られた1つの引数を作成し、別々の引数に展開します。例として、次のことを考慮してください。$IFS
"$@"
for i in "$@"; do echo "@ '$i'"; done
for i in "$*"; do echo "* '$i'"; done
複数の引数で実行する場合:
./testvar foo bar baz 'long arg'
@ 'foo'
@ 'bar'
@ 'baz'
@ 'long arg'
* 'foo bar baz long arg'
詳細については:
http://www.gnu.org/software/bash/manual/bashref.html#Special-Parameters
$*
1つから開始して位置パラメータに展開します。展開が二重引用符で囲まれている場合、各パラメーターの値がIFS特殊変数の最初の文字で区切られた単一の単語に展開されます。つまり、"$*"
と同等です"$1c$2c..."
。ここで、cはIFS変数の値の最初の文字です。IFSが設定されていない場合、パラメーターはスペースで区切られます。IFSがnullの場合、パラメーターは区切り文字を介さずに結合されます。
$@
1つから開始して位置パラメータに展開します。展開が二重引用符で囲まれている場合、各パラメーターは個別の単語に展開されます。つまり、単語内で二重引用符で囲まれた展開が発生した場合、最初のパラメーターの展開は元の単語の最初の部分と結合され、最後のパラメーターの展開は元の単語の最後の部分と結合されます"$@"
。"$1" "$2" ....
語。位置パラメータがなく、何"$@"
も$@
展開しない場合(つまり、それらが削除される場合)。
私の POV との主な違いは、元"$@"
の引数の数が維持されることです。できる唯一の形です。
たとえば、ファイル my_script に次のものが含まれているとします。
#!/bin/bash
main()
{
echo 'MAIN sees ' $# ' args'
}
main $*
main $@
main "$*"
main "$@"
### end ###
そして、私はそれを次のように実行します:
my_script 'a b c' d e
この出力が得られます:
MAIN sees 5 args
MAIN sees 5 args
MAIN sees 1 args
MAIN sees 3 args