$foo = *がエラーを引き起こさないのはなぜですか?

$foo = *がエラーを引き起こさないのはなぜですか?

シェルが特定のタイプの文字を拡張することを学びました。だから文章を書くとき:

$ echo *

ディレクトリとファイルのリストを取得しました。次のような結果が得られたとしましょう。

Applications Desktop Documents

それでは、私が書いているとしましょう。

$ foo=Applications Desktop Documents

私は得る:

-bash: Desktop: command not found

大丈夫ですが、書くとき:

$ foo=*

それは効果がありますが、なぜですか?私は*が拡張され、上記のようなエラーが発生しなければならないと確信しています。

執筆中

$ echo ${#foo}

*がfooに保存されたことを示す答え1を取得します。

ジョブで*が拡張されないのはなぜですか?使ってみると増えます。

$ echo ${foo}

ありがとう

答え1

変数の割り当て中はパス名拡張は行われません。以下はbashのマンページから抜粋したものです。

値を指定しないと、変数に空の文字列が割り当てられます。すべての値には、チルダ拡張、パラメータおよび変数拡張、コマンド置換、算術拡張、および引用符の削除があります(下記の拡張を参照)。変数に整数属性セットがある場合、$((...))拡張が使用されていなくても、値は算術式として評価されます(下記の算術拡張を参照)。以下の特殊パラメータで説明されているように、「$ @」を除いて単語の区切りは行われません。パス名の拡張は行われません。

割り当てを実行すると、foo=*foo変数にリテラルが含まれます*。後で引用符なしで変数を使用すると、パラメータは最初にリテラルに展開され、次にパス名*拡張が発生します。*パラメータ拡張を引用して、リテラルが含まれていることを確認できます。

$ foo=*
$ echo "$foo"
*

配列を割り当てるときのように、bashにはこの規則に対するいくつかの例外があります。

$ foo=(*)

上記の例では、パス名の拡張はすぐに発生し、配列にはglobと一致するファイルのリストが含まれています。

答え2

シェルがワイルドカードをglobに拡張できない場合は、文字通り処理されます。

$ cd scratch
$ rm *
$ foo=*
$ echo $foo
*
$ echo "$foo"
*
$ touch file
$ echo $foo
file
$ echo "$foo"
*

関連情報