~からhttps://unix.stackexchange.com/a/32227/674
二重引用符を使用しないのが安全な主な場所は次のとおりです。
- 割り当てでは:(しかし、
foo=$bar
例えば配列割り当て内では二重引用符が必要です。)export "foo=$bar"
array=("$a" "$b")
$bar
これは、値を割り当てるときに二重引用符が必要ないという意味ですかfoo=$bar
?なぜ?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には多数の拡張機能があり、すべて特定の順序で発生します。一般に、何かが「安全」であると言うとき、望ましくない噴射が発生しないことを意味します。この意味で:
「安全」です。つまり、二重引用符は必要ありません。 bashのマニュアルを引用すると、次のようになります。
次の形式のステートメントを使用して変数を割り当てることができます。
name=[value]
値を指定しないと、変数に空の文字列が割り当てられます。すべての値が渡されますチルダ拡張、パラメータおよび変数拡張、コマンド置換、算術拡張、および引用符の削除(下記の拡張を参照)。
単語分割は行われません。そのため、これは非常に安全であり、実行が失敗したりファイルが削除されるなどの
bar="rm asdf"; foo=$bar;
クレイジーな状況は発生しません。しかし何$foo
eval $foo
〜する変数拡張が発生します。foo="Tomatoes are $50"
foo
コンテンツを所有しますTomatoes are 0
。これはあなたが望むものかもしれないし、そうでないかもしれません。同様に動作します。
foo="rm asdf"; export bar=$foo
ファイルは削除されずに正しく解析されますfoo="rm asdf"; array=($foo)
。配列の場合、単語分割は実際にする発生するため、array
willの最初の要素はですrm
。また、これらの両方で他の拡張機能も入手できます。また、この場合、単語分割が発生すると確信しています
export
。エクスポートはすべての単語を引数として受け入れ、echo $foo
引用符が不要なものと同様に予想どおりに解析します。
これらの例のうち、トークン化が発生して具体的な効果があるため、配列の例が最も安全ではない例だと思います。したがって、この場合は二重引用符が必要です。