web-dev-qa-db-ja.com

Bashの「$ @」と「$ *」の違いは何ですか?

どちらもコマンドライン引数をすべて保存しているように思えます。

だから、2つの間に違いはありますか?

63
Debugger

違いはわずかです。 "$*"$IFS変数で区切られた1つの引数を作成しますが、"$@"は個別の引数に展開されます。例として、以下を検討してください。

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特殊変数の最初の文字で区切られた単一のWordに展開されます。つまり、"$*""$1c$2c..."と同等です。cはIFS変数の値の最初の文字です。 IFSが設定されていない場合、パラメーターはスペースで区切られます。 IFSがヌルの場合、パラメーターはセパレーターを介さずに結合されます。

$@

1から始まる定位置パラメーターに展開します。二重引用符内で展開すると、各パラメーターが個別のWordに展開されます。つまり、"$@""$1" "$2" ....と同じです。二重引用符で囲まれた展開がWord内で発生する場合、最初のパラメーターの展開は元のWordの先頭部分と結合され、最後の展開はパラメータは、元のWordの最後の部分と結合されます。位置パラメータがない場合、"$@"$@は何も展開されません(つまり、削除されます)。

95
Hudson

key私のPOVとの違いは、"$@"は、引数の元の数を保持します。それはonly形式です。

たとえば、ファイル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
57
Art Swri