変数を拡張するには二重引用符が必要であることを読みました。
if [ -n "$test" ]; then echo '$test ok'; else echo '$test null'; fi
期待どおりに動作しますが、
if [ -n $test ]; then echo '$test ok'; else echo '$test null'; fi
$test ok
nullの場合でも常に呼び出されます$test
。
しかし、なぜ引用符が必要ないのですかecho $test
?
ベストアンサー1
すべての変数には常に引用符が必要です。リスト言い換えれば、変数を引用しないままにするという3つの副作用を実際に望まない限り、変数はどこからでも複数の値に拡張できます。
リストコンテキストには、[
またはecho
、for i in <here>
配列への割り当てなどの単純なコマンドのパラメータが含まれます。他のコンテキストもあり、変数も参照する必要があります。妥当な理由がない限り、常に変数を引用するのが最善です。
考えると引用符なし(リストコンテキストで)次のように分割+グローバルオペレーター。
まるでecho $test
。echo glob(split("$test"))
puts("foo")
他のほとんどの言語では、変数(たとえば)の周りではなく、固定文字列の周りに引用符を付けますが、puts(var)
シェルではその逆です。つまり、シェルのすべてはすべて文字列です。したがって、すべてに引用符を付けるのは面倒であり、あなたはecho test
それを必要としません"echo" "test"
。シェルでは、引用符は他の目的、つまり特定の文字の特別な意味を回避したり、特定の拡張子の動作に影響を与えるために使用されます。
[ -n $test ]
orでは、echo $test
シェルは分割$test
(デフォルトでは空白)を実行し、ファイル名の生成(すべての「*
?」...パターンを一致するファイルのリストに拡張)し、その引数のリストを[
orecho
コマンドに渡します。
もう一度考えてみてください"[" "-n" glob(split("$test")) "]"
。空白または空白(spc、tab、nl)のみを含む場合、$test
分割+glob演算子は空のリストを返すため、「-n」が空の文字列であることを確認するテスト[ -n $test ]
です。"[" "-n" "]"
しかし、$test
「*」または「= foo」なら、何が起こるのか想像してみてください。
、および(引用符なし)には4つのパラメータが渡されます。[ -n "$test" ]
これは私たちが望むものです。[
"["
"-n"
""
"]"
echo
渡すかどうかは[
違いはありませんecho
。空のパラメータを渡してもパラメータをまったく渡さなくても、同じ内容が出力される点だけが異なります。
また、見ることができますこの同様の質問に対する答え[
コマンドと設定の[[...]]
詳細。