Linuxでダブルブラケット条件付きテストを使用する方法

公開: 2022-01-29
fatmawati achmad zaenuri / Shutterstock.com

条件付きテストは、論理式の結果に従ってLinuxBashスクリプトの実行フローを分岐します。 二重括弧の条件付きテストは構文を大幅に簡素化しますが、それでも独自の落とし穴があります。

シングルブラケットとダブルブラケット

Bashはtestコマンドを提供します。 これにより、論理式をテストできます。 式は、真または偽の応答を示す回答を返します。 真の応答は、ゼロの戻り値で示されます。 ゼロ以外はfalseを示します。

&&演算子を使用してコマンドラインでコマンドを連鎖させると、この機能が使用されます。 コマンドは、前のコマンドが正常に完了した場合にのみ実行されます。

テストが真の場合、「はい」という単語が印刷されます。

 test 15 -eq 15 && echo "はい"
 test 14 -eq 15 && echo "はい" 

Bashテストコマンドの簡単な例

単一ブラケットの条件付きテストは、 testコマンドを模倣します。 式を角かっこ「 [ ] 」で囲み、 testコマンドと同じように動作します。 実際、これらは同じプログラムであり、同じソースコードから作成されています。 唯一の操作上の違いは、 testバージョンと[バージョンがヘルプリクエストを処理する方法です。

これはソースコードからのものです:

 / * --helpまたは--versionを認識しますが、
"["形式、最後の引数が "]"でない場合。 直接使用
受け入れを回避するために、parse_long_optionsではなく解析
略語。 POSIXでは、「[-help」と「[--version」を次のように使用できます。
通常のGNU動作がありますが、「test--help」が必要です。
および「test--version」を使用して、ステータス0でサイレント終了します。* /
広告

test[に助けを求め、Bashに送信された応答コードを確認することで、この効果を確認できます。

 test --help
 エコー$?
 [  - ヘルプ
エコー$? 

テストで--helpを使用し、[

test[はどちらもシェルビルトインです。つまり、Bashに直接ベイクされます。 ただし、 [のスタンドアロンバイナリバージョンもあります。

 タイプテスト
タイプ [
 whereis [ 

さまざまなタイプの[およびテストコマンドを見つける

対照的に、二重括弧の条件付きテスト[[および]]キーワードです。 [[および]]も論理テストを実行しますが、構文は異なります。 それらはキーワードであるため、シングルブラケットバージョンでは機能しないいくつかの優れた機能を使用できます。

二重角かっこキーワードはBashでサポートされていますが、他のすべてのシェルで使用できるわけではありません。 たとえば、Kornシェルはそれらをサポートしますが、プレーンな古いシェルshはサポートしません。 すべてのスクリプトは次の行で始まります。

 #!/ bin / bash

これにより、スクリプトを実行するためにBashシェルを呼び出すことが保証されます。

関連: Windows10でBashシェルスクリプトを作成して実行する方法

ビルトインとキーワード

compgenプログラムを使用して、ビルトインを一覧表示できます。

 compgen -b | fmt -w 70
広告

fmtを介して出力をパイプ処理しないと、それぞれが独自の行に組み込まれている長いリストが得られます。 この場合、ビルトインが1つの段落にグループ化されているのを確認すると便利です。

Bashビルトインの一覧表示

test[リストに]が表示されていますが、 ]はリストされていません。 [コマンドは、式の終わりに到達したことを検出するために終了]を探しますが、 ]は別個の組み込みではありません。 これは、パラメータリストの終わりを示すために[に与える信号にすぎません。

キーワードを表示するには、次を使用できます。

 compgen -k | fmt -w 70 

Bashキーワードの一覧表示

[[]]キーワードは両方ともリストに含まれています。これは、 [[は1つのキーワードであり、 ]]は別のキーワードであるためです。 それらは、 ifficaseesacのように、一致するペアです。

Bashがスクリプト(またはコマンドライン)を解析していて、一致する終了キーワードを持つキーワードを検出すると、Bashはそれらの間に表示されるすべてのものを収集し、キーワードがサポートする特別な処理を適用します。

ビルトインを使用すると、ビルトインコマンドに続くものは、他のコマンドラインプログラムのパラメーターとまったく同じように渡されます。 これは、変数値のスペースなどに関して、スクリプトの作成者が特別な注意を払う必要があることを意味します。

シェルグロブ

ダブルブラケット条件付きテストでは、シェルグロブを利用できます。 これは、アスタリスク「 * 」が「何でも」を意味するように展開されることを意味します。

広告

次のテキストをエディタに入力またはコピーして、「whelkie.sh」というファイルに保存します。

 #!/ bin / bash

stringvar = "Whelkie Brookes"

if [["$ stringvar" == * elk *]];
それから
  echo「警告にはシーフードが含まれています」
それ以外
  エコー「軟体動物を含まない」
fi

スクリプトを実行可能にするには、 -x (実行)オプションを指定してchmodコマンドを使用する必要があります。 試してみたい場合は、この記事のすべてのスクリプトに対してこれを行う必要があります。

 chmod + x whelkie.sh 

chmodを使用してスクリプトを実行可能にする

スクリプトを実行すると、文字列「elk」が文字列「Whelkie」で検出されたことがわかります。これは、他の文字で囲まれているかどうかに関係ありません。

 ./whelkie.sh 

whelkie.shスクリプトの実行

注意すべき点の1つは、検索文字列を二重引用符で囲まないことです。 そうした場合、グロブは発生しません。 検索文字列は文字通りに扱われます。

他の形式のシェルグロブが許可されます。 疑問符「 ? 」は単一の文字に一致し、単一の角括弧は文字の範囲を示すために使用されます。 たとえば、どちらのケースを使用するかわからない場合は、両方の不測の事態を範囲でカバーできます。

 #!/ bin / bash

stringvar = "Jean-Claude van Clam"

if [["$ stringvar" == * [cC] lam *]];
それから
  echo「警告にはシーフードが含まれています。」
それ以外
  エコー「軟体動物から解放されました。」
fi

このスクリプトを「damme.sh」として保存し、実行可能にします。 これを実行すると、条件ステートメントがtrueに解決され、ifステートメントの最初の句が実行されます。

 ./damme.sh 

damme.shスクリプトの実行

文字列の引用

文字列を二重引用符で囲むことについては前に説明しました。 そうした場合、シェルのグロブは発生しません。 慣例では良い習慣とされていますが、 [[および]]を使用する場合は、スペースが含まれている場合でも、文字列変数を引用符で囲む必要はありません。 次の例を見てください。 $stringvar変数と$surname文字列変数の両方にスペースが含まれていますが、条件ステートメントではどちらも引用符で囲まれていません。

 #!/ bin / bash

stringvar = "van Damme"
surname = "van Damme"

if [[$ stringvar == $ surname]];
それから
echo "名前が一致します。"
それ以外
echo "名前が一致しません。"
fi
広告

これを「surname.sh」というファイルに保存して実行可能にします。 以下を使用して実行します。

 ./surname.sh 

surname.shスクリプトを実行する

両方の文字列にスペースが含まれているにもかかわらず、スクリプトは成功し、条件ステートメントはtrueに解決されます。 これは、スペースを含むパスとディレクトリ名を処理するときに役立ちます。 ここで、変数に有効なディレクトリ名が含まれている場合、 -dオプションはtrueを返します。

 #!/ bin / bash

dir = "/ home / dave / Documents / Needs Work"

if [[-d $ {dir}]];
それから
  エコー「ディレクトリ確認済み」
それ以外
  エコー「ディレクトリが見つかりません」
fi

自分のコンピュータのディレクトリを反映するようにスクリプトのパスを変更し、テキストを「dir.sh」というファイルに保存して実行可能にすると、これが機能することがわかります。

 ./dir.sh 

dir.shスクリプトの実行

関連: Bashで変数を操作する方法

ファイル名GlobbingGotchas

[ ][[ ]]の興味深い違いは、グロブが含まれるファイル名に関連しています。 「* .sh」の形式は、すべてのスクリプトファイルに一致します。 単一のスクリプトファイルがない限り、単一の角かっこ[ ]の使用は失敗します。 複数のスクリプトを検索すると、エラーがスローされます。

これは、単一括弧の条件付きのスクリプトです。

 #!/ bin / bash

if [-a * .sh];
それから
  echo "スクリプトファイルが見つかりました"
それ以外
  echo "スクリプトファイルが見つかりませんでした"
fi

このテキストを「script.sh」に保存して実行可能にしました。 ディレクトリにあるスクリプトの数を確認してから、スクリプトを実行しました。

 ls
 ./script.sh 

script.shスクリプトを実行する

広告

Bashはエラーをスローします。 1つを除くすべてのスクリプトファイルを削除して、スクリプトを再度実行しました。

 ls
 ./script.sh 

ディレクトリ内の単一のスクリプトでscript.shスクリプトを実行する

条件付きテストはtrueを返し、スクリプトはエラーを引き起こしません。 二重角かっこを使用するようにスクリプトを編集すると、3番目のタイプの動作が提供されます。

 #!/ bin / bash

if [[-a * .sh]];
それから
  echo "スクリプトファイルが見つかりました"
それ以外
  echo "スクリプトファイルが見つかりませんでした"
fi

これを「dscript.sh」というファイルに保存して実行可能にしました。 多くのスクリプトが含まれているディレクトリでこのスクリプトを実行してもエラーは発生しませんが、スクリプトはスクリプトファイルを認識できません。

二重括弧を使用した条件文は、ディレクトリに実際に「* .sh」というファイルがあるというまれなケースでのみtrueに解決されます。

 ./dscript.sh 

dscript.shスクリプトの実行

論理積と論理積

二重角かっこを使用すると、 &&||を使用できます論理ANDおよびOR演算子として。

10は10に等しく 25は26未満であるため、このスクリプトは条件ステートメントをtrueに解決する必要があります。

 #!/ bin / bash

最初= 10
秒= 25

if [[first -eq 10 && second -lt 26]];
それから
  エコー「条件が満たされました」
それ以外
  エコー「条件が失敗しました」
fi
広告

このテキストを「and.sh」というファイルに保存し、実行可能にして、次のコマンドで実行します。

 ./and.sh 

and.shスクリプトの実行

スクリプトは期待どおりに実行されます。

今回は||を使用しますオペレーター。 10は15より大きくないが、25は26未満であるため、条件ステートメントはtrueに解決されます。最初の比較または2番目の比較のいずれかが真である限り、条件ステートメントは全体としてtrueに解決されます。

このテキストを「or.sh」として保存し、実行可能にします。

 #!/ bin / bash

最初= 10
秒= 25

if [[first -gt 15 || 少尉26]];
それから
  echo「条件が満たされました。」
それ以外
  echo "条件が失敗しました。"
fi
 ./or.sh 

or.shスクリプトの実行

正規表現

二重括弧の条件ステートメントでは、 =~演算子を使用できます。これにより、文字列内の正規表現検索パターンがステートメントの残りの半分に適用されます。 正規表現が満たされている場合、条件ステートメントは真であると見なされます。 正規表現で一致するものが見つからない場合、条件ステートメントはfalseに解決されます。

関連: Linuxで正規表現(regexes)を使用する方法

このテキストを「regex.sh」というファイルに保存し、実行可能にします。

 #!/ bin / bash

words = "one two three"
WordsandNumbers = "one 1 2 2 3 3"
email = "[email protected]"

mask1 = "[0-9]"
mask2 = "[A-Za-z0-9 ._%+-] + @ [A-Za-z0-9 .-] +。[A-Za-z] {2,4}"

if [[$ words =〜$ mask1]];
それから
  echo "\" $ words \ "には数字が含まれています。"
それ以外
  echo "\" $ words \ "に数字が見つかりません。"
fi

if [[$ WordsandNumbers =〜$ mask1]];
それから
  echo "\" $ WordsandNumbers \ "には数字が含まれています。"
それ以外
  echo "\" $ WordsandNumbers \ "に数字が見つかりません。"
fi

if [[$ email =〜$ mask2]];
それから
  echo "\" $ email \ "は有効な電子メールアドレスです。"
それ以外
  echo "\" $ email \ "を解析できませんでした。"
fi

二重括弧の最初のセットは、正規表現として文字列変数$mask1を使用します。 これには、0から9の範囲のすべての桁のパターンが含まれます。 この正規表現を$words文字列変数に適用します。

2番目の二重括弧のセットも正規表現として文字列変数$mask1を使用しますが、今回は$WordsandNumbers文字列変数とともに使用します。

広告

二重括弧の最後のセットは、文字列変数$mask2でより複雑な正規表現マスクを使用します。

  • [A-Za-z0-9 ._%+-] + :これは、大文字または小文字、または0から9までの任意の数字、またはピリオド、アンダースコア、パーセント記号、またはプラスまたはマイナス記号である任意の文字に一致します。 「 [] 」の外側の「 + 」は、見つかった数の文字に対してそれらの一致を繰り返すことを意味します。
  • @ :これは「@」文字のみに一致します。
  • [A-Za-z0-9 .-] + :これは、大文字または小文字、0から9までの任意の数字、またはピリオドまたはハイフンである任意の文字に一致します。 「 [ ] 」の外側の「 + 」は、見つかった数の文字に対してそれらの一致を繰り返すことを意味します。
  • :これは「。」と一致します文字のみ。
  • [A-Za-z] {2,4} :これは大文字または小文字に一致します。 「 {2,4} 」は、2文字以上、4文字以内で一致することを意味します。

それをすべてまとめると、正規表現マスクは、電子メールアドレスが正しく形成されているかどうかをチェックします。

スクリプトテキストを「regex.sh」というファイルに保存し、実行可能にします。 スクリプトを実行すると、この出力が得られます。

 ./regex.sh 

regex.shスクリプトの実行

正規表現が数字を探しているが、 $words文字列変数に保持されている値に数字がないため、最初の条件付きステートメントは失敗します。

$WordsandNumbers文字列変数に数字が含まれているため、2番目の条件付きステートメントは成功します。

広告

電子メールアドレスが適切にフォーマットされているため、最後の条件ステートメントは成功します。つまり、trueに解決されます。

たった1つの条件

ダブルブラケット条件付きテストは、スクリプトに柔軟性と読みやすさをもたらします。 条件付きテストで正規表現を使用できることは、 [[および]]の使用方法を学ぶことを正当化します。

スクリプトがBashのようにそれらをサポートするシェルを呼び出すことを確認してください。

関連: Bashで知っておく必要のある15の特殊文字