400

多くの 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

$*とはどう違い$@ますか?
いつ前者を使用し、いつ後者を使用する必要がありますか?

4

5 に答える 5

515

特別なパラメーターが引用符で囲まれている場合、違いが現れます。違いを説明しましょう:

$ 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 つのスペースがあることに注意してください。

$ 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
于 2012-09-07T10:46:32.987 に答える
319

Bash Hackers Wikiの便利な概要表:

構文 効果的な結果
$* $1 $2 $3 … ${N}
$@ $1 $2 $3 … ${N}
"$*" "$1c$2c$3c…c${N}"
"$@" "$1" "$2" "$3" … "${N}"

ここcで、3 行目はシェル変数で$IFSあるInput Field Separatorの最初の文字です。

引数がスクリプト変数に格納され、引数にスペースが含まれていることが予想される場合は"$*"、入力フィールド区切り文字を tab に設定してトリックをIFS=$'\t'使用することを心からお勧めします。

于 2015-01-22T22:18:53.683 に答える
51

$*

1 から始まる定位置パラメーターに展開されます。展開が二重引用符内で発生すると、各パラメーターの値が IFS 特殊変数の最初の文字で区切られた単一の単語に展開されます。つまり、「$*」は「$1c$2c...」と同等です。ここで、c は IFS 変数の値の最初の文字です。IFS が設定されていない場合、パラメーターはスペースで区切られます。IFS が null の場合、パラメータはセパレータを介さずに結合されます。

$@

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

出典:バッシュマン

于 2012-09-07T08:36:55.173 に答える
21

$@ は $* と同じですが、各パラメーターは引用符で囲まれた文字列です。つまり、パラメーターは解釈や展開なしでそのまま渡されます。これは、特に、引数リスト内の各パラメーターが個別の単語として認識されることを意味します。

もちろん、"$@" は引用符で囲む必要があります。

http://tldp.org/LDP/abs/html/internalvariables.html#ARGLIST

于 2012-09-07T08:32:33.557 に答える