web-dev-qa-db-ja.com

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

例えば.

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

if [ $FOO = "true" ]; then

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

9
Ryan

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

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

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

6
200_success

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

次の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'を保持します。 [テストキーワードは、最初の引数または2番目の引数が演算子であることを期待しているため、何を実行するかわかりません。

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

もう一つの例:

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

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

3

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

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

の中に "$FOO"ケースでは、合計で変数を使用して、スペースの問題からあなたを隔離するマッチを作成します。

ただし、$FOOとifステートメントに影響する特殊なケースがあります。

0
mdpc