bash変数を二重引用符で比較する方法

bash変数を二重引用符で比較する方法

このコードがあります

STATUS=`echo "test"`


if [ $STATUS == "test" ]; then
   exit 0
fi

私はすべてを試しましたが、それを達成することはできません。

頑張った

"$STATUS" == "test"
eval $STATUS == "test"
${STATUS[@]} == "test"

働く唯一のこと

$STATUS == \"test\"

答え1

質問のコードが機能します。これは、対応するexit 0文が実行されることを意味します。

あなたの

STATUS=`echo "test"`

同じですか?

STATUS="test"

そして(この場合)

STATUS=test

つまり、変数は値としてSTATUS指定されますtest(値に二重引用符はありません)。

この値をテストするには、test次のようにします。

if [ "$STATUS" = "test" ]

または

if [[ $STATUS == "test" ]]

次のSTATUS値がある場合"test"

STATUS='"test"'

次に、その文字列を比較して使用します。

if [ "$STATUS" = '"test"' ]

または

if [[ $STATUS == '"test"' ]]

また見なさい:

答え2

エスケープされた引用符は、\"test\"シェルの引用規則に若干の混乱があると考えさせます。コードの最初の部分は期待どおりに機能しますが、機能してはいけません$STATUS == \"test\"(作成しているかSTATUS=`echo '"test"'`それと似ていない限り)。

これらの混乱を適切に説明するには、いくつかのシェルの概念を説明する必要があります。


引用する

POSIXシェルでは、引用は最も重要なメカニズムの1つです。残念ながら、これは非常に混乱したトピックでもあり、誤って使用すると、スクリプトでバグや奇妙な動作が発生する重要な原因になる可能性があります。

デフォルトのルールは次のとおりです。

  1. エスケープ文字\:除いて、次の文字のリテラル値を保持します<newline>
  2. 二重引用符"$、および(記録拡張が有効な場合)を除いて、引用符内のすべての文字のリテラル値を保持します。`\!
  3. アポストロフィ'例外なしで引用符内のすべての文字のリテラル値を保持します。

コマンドの置き換え

コマンド置換を使用すると、コマンド出力がコマンド自体を置き換えることができます。構文は$(command)or`command`ですが、電子が優先されます。

テストコマンド

このコマンド(POSIXおよびbash、ksh、zshなどのシェルではこのコマンドとも呼ばれますtest)を使用すると、便利な条件付きおよび算術式を多く使用できます。たとえば、特定の汎用ファイルが存在して読み取れるかどうか、2つの文字列が等しいかどうか、または1つの数字が別の数字よりも大きいかどうかを確認できます。[[[


それでは、コードを分析してみましょう。

STATUS=`echo "test"`

ここでコマンドの置き換えは次のように書くことができるので役に立ちませんSTATUS="test"。二重引用符はで印刷されないため、そのecho値はSTATUS保持されます。test

if [ $STATUS == "test" ]; then
   exit 0
fi

これには少なくとも3つの潜在的な落とし穴があります。

  1. 引用されていない内容は$STATUS単語分割の影響を受ける可能性があります。
  2. ==これはPOSIXではなく構文です。=携帯性を重視する場合は、これを使用してください。
  3. ifそして、この場合はすでに意図した作業を行うexit 0ので役に立ちません。[

また、前のコード行と同様に、二重引用符は文字通り使用されないため、生成されたコマンド(引用符を展開して削除した後)は[ test = test ]正しいものです。


しかし、目標が"test"価値を持っているSTATUSなら

STATUS=\"test\"
STATUS="\"test\""
STATUS='"test"'

すべて有効な操作です。

[ "$STATUS" = \"test\" ]
[ "$STATUS" = "\"test\"" ]
[ "$STATUS" = '"test"' ]

すべて有効な条件式です。

答え3

使用しているシェルによって、この問題の回避策が異なる場合があります。また、スクリプトの「echo $STATUS」行と比較する前に、$STATUSに「test」が含まれていることを確認してください。変数の内容を調べることは、デバッグに非常に役立ちます。可能性は希薄ですが、他のプログラムがこれを設定している可能性は少なく、この場合は明らかに失敗します。

一般的に言って、あなたが書くコードはしなければならない働くそうでない場合、問題はスクリプトの他のコード、シェル自体、または他のプログラム干渉である可能性があります。エクスポートを使用して、変数をシステム全体にエクスポートして、変数が正しく設定されていることを確認できます。これにはすべての干渉値を含める必要があります。他のプログラムが干渉している場合、変数が変更されるのが好きではない可能性があることに注意してください。

参考までに以下の情報をお知らせします。

変数を単純な状態(例:「テスト」)に設定する最良の方法は次のとおりです。

VARIABLE="value"

echoを使用してテキストを変数として返すことはできますが、testなどの文字列を使用するとそれを行う理由はありません。制御文字(改行文字など)を挿入するためにecho -eまたはprintfを使用する予定がない場合。

文字列を比較するのに推奨される方法は、次のいずれかの方法を使用することです。

if [ "$VARIABLE" = "value" ]; then
if [[ $VARIABLE == value ]]; then

まだ試していない場合は、クラシックテストとも呼ばれる[代わりに拡張テストとも呼ばれる新しい[[]を試してください。

http://wiki.bash-hackers.org/commands/classictest

http://wiki.bash-hackers.org/syntax/ccmd/conditional_expression

テストオペレーターの詳細を知りたい場合は、より多くの情報を得るのに役立つ素晴らしいリソースをご覧ください。

関連情報