`foo=$bar` を指定するときに二重引用符 `$bar` が不要なのはなぜですか? [コピー]

`foo=$bar` を指定するときに二重引用符 `$bar` が不要なのはなぜですか? [コピー]

~からhttps://unix.stackexchange.com/a/32227/674

二重引用符を使用しないのが安全な主な場所は次のとおりです。

  • 割り当てでは:(しかし、 foo=$bar例えば配列割り当て内では二重引用符が必要です。)export "foo=$bar"array=("$a" "$b")
  1. $barこれは、値を割り当てるときに二重引用符が必要ないという意味ですかfoo=$bar?なぜ?

  2. export "foo=$bar"たとえば、配列の割り当てに二重引用符を使用するのはなぜですかarray=("$a" "$b")

ありがとうございます。

答え1

foo=$bar

はい安全なぜなら仕事、スカラー割り当て構文を使用して、スカラー変数に値を割り当てます。それスカラーコンテキスト、1つの値しか保存できないため、$var分割またはglobは意味がありません$bar。拡張によって複数の単語が生成される場合、シェルはその単語を$foo

以下を使用すると状況が異なります。

foo=($bar)

配列変数に割り当てる位置です。これはリストのコンテキストです。配列要素に複数の単語を割り当てています。分割+グローブが発生します。

exportまた、一部のシェルでは、// local/ typeset/declareなどの二重属性に注意してくださいreadonly(参照ローカル変数の割り当てには引用符が必要ですか?)

あなたは次のことを知るでしょう:

foo=$bar

割り当て文として解析されます。

"foo"=$bar

コマンドを実行してみてくださいfoo=content_of_bar(barの内容は分割+globの影響を受けます)。

export(and other local/ typeset...)がキーワードであり、組み込みコマンドであるシェル(最新バージョンのksh、bash、およびzsh)では、次の場所にあります。

export foo=$bar

exportとみなされるキーワードfoo=$bar割り当てとして$bar分割+globの影響を受けません。しかし、export考慮を止めるには多くの努力は必要ありません。キーワード。この場合、これは単純なコマンドとして扱われ、他のコマンドの引数と同様にSplit + globが発生します。

キーワードとして扱われてもexport引数が変数代入のように見えない場合(上記のように"foo"=$bar)、通常の引数として扱われ、再び分割+globの適用を受けます。

答え2

2つの質問に答えるには、まず「セキュリティ」とは何かを知る必要があります。 Bashには多数の拡張機能があり、すべて特定の順序で発生します。一般に、何かが「安全」であると言うとき、望ましくない噴射が発生しないことを意味します。この意味で:

  1. 「安全」です。つまり、二重引用符は必要ありません。 bashのマニュアルを引用すると、次のようになります。

    次の形式のステートメントを使用して変数を割り当てることができます。

              name=[value]
    

    値を指定しないと、変数に空の文字列が割り当てられます。すべての値が渡されますチルダ拡張、パラメータおよび変数拡張、コマンド置換、算術拡張、および引用符の削除(下記の拡張を参照)

    単語分割は行われません。そのため、これは非常に安全であり、実行が失敗したりファイルが削除されるなどのbar="rm asdf"; foo=$bar;クレイジーな状況は発生しません。しかし何$fooeval $foo〜する変数拡張が発生します。

    foo="Tomatoes are $50"fooコンテンツを所有しますTomatoes are 0。これはあなたが望むものかもしれないし、そうでないかもしれません。

  2. 同様に動作します。 foo="rm asdf"; export bar=$fooファイルは削除されずに正しく解析されますfoo="rm asdf"; array=($foo)。配列の場合、単語分割は実際にする発生するため、arraywillの最初の要素はですrm

    また、これらの両方で他の拡張機能も入手できます。また、この場合、単語分割が発生すると確信していますexport。エクスポートはすべての単語を引数として受け入れ、echo $foo引用符が不要なものと同様に予想どおりに解析します。

これらの例のうち、トークン化が発生して具体的な効果があるため、配列の例が最も安全ではない例だと思います。したがって、この場合は二重引用符が必要です。

関連情報