シェルスクリプトの「if」ステートメントで変数を引用する


9

例えば

if [ "$FOO" = "true" ]; then

if [ $FOO = "true" ]; then

何が違うのですか?2つのステートメントの両方とも機能するようです。



@DennisWilliamson不正解です。(不等号)およびパターンマッチング演算子の右側に引用符が必要です。
Gilles「SO-邪悪になるのをやめる」


@ギレス:時々そうではない。スペースを含むリテラル文字列の場合、またはリテラル文字列または文字どおり取得したいグロブ文字を含む変数の場合は、右側を引用符で囲む必要がありますa='foo bar'; [[ $a == "foo bar" ]]。ただし、グロブ文字を含まない変数は、次のものである必要はありません[[ $a == $a ]]。単語の展開は、二重角括弧内では実行されません。そして、正規表現マッチングのために、右側のパターンが引用されてはならないか、それが文字列リテラルとして解釈されます[[ $a =~ .*oo.*r ]](パターンが...しかし、代わりに、非引用された変数でなければなりません
一時停止追って通知があるまで。

文字通りここに組み込まれているのです)。グロブスタイルのパターンマッチングでは、リテラルか変数内かに関わらず、グロブ文字を引用符で囲まないでください[[ $a == foo* ]]。私のリテラル文字列の例以外に、引用の要件の追加の例を提供できますか?
追って通知があるまで一時停止。

回答:


6

の値が$FOOワイルドカード文字を含まない単一の単語である\[*?場合、2つは同一です。

場合は$FOO割り当てられていない、または空の、または複数の単語(すなわち、空白文字が含まれているか$IFS)、その後、引用符で囲まれていないバージョンが構文エラーです。たまたまそれが単語の正しいシーケンスである場合(など0 -eq 0 -o false)、結果は任意である可能性があります。したがって、シェルスクリプトでは常に変数を引用することをお勧めします。

ちなみに、"true"引用する必要はありません。


3

どのような問題が発生するかを説明するために、ここにいくつかの例を示します。

次の2つの変数があるとします。

FOO="some value"
BAR="some value"

これで、まったく同じ文字列/値を保持する2つの変数があります。あなたの場合、結果をテストするためにいくつかのifステートメントを実行した場合:

if [ $FOO = "$BAR" ]; then echo "match"; else echo "no match"; fi

この時点でが得られbash: [: too many argumentsます。引用符で囲まれていない$ FOOは、3つの値、つまりを保持します'[ , some , value'[testキーワードは、最初の引数または2番目の引数が演算子であることを期待しているため、何を実行するかわかりません。

「$ FOO」を引用するときはif、単語分割が行われない正しい値を調べるように明示的に指示します。

もう一つの例:

my_file="A random file.txt"
  • 実行とrm $my_fileは、「A」「ランダム」「file.txt」を削除して、3つのファイルにすることです。
  • 実行rm "$my_file"すると、1つのファイルを作成する「ランダムなfile.txt」が削除されます。

私がこれらの例と混同していないことを願っています。


0

この特定のケースでは違いはありません。

ただし、$FOOスペースまたはいくつかの特殊文字が含まれている場合は、問題が発生します。

この"$FOO"場合、合計で変数を使用して、スペースの問題からあなたを守るマッチを作成します。

ただし、使用$FOOしていて特別な場合がある場合は、ifステートメントに影響します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.