Linuxでダブルブラケット条件付きテストを使用する方法
公開: 2022-01-29条件付きテストは、論理式の結果に従ってLinuxBashスクリプトの実行フローを分岐します。 二重括弧の条件付きテストは構文を大幅に簡素化しますが、それでも独自の落とし穴があります。
シングルブラケットとダブルブラケット
Bashはtest
コマンドを提供します。 これにより、論理式をテストできます。 式は、真または偽の応答を示す回答を返します。 真の応答は、ゼロの戻り値で示されます。 ゼロ以外はfalseを示します。
&&
演算子を使用してコマンドラインでコマンドを連鎖させると、この機能が使用されます。 コマンドは、前のコマンドが正常に完了した場合にのみ実行されます。
テストが真の場合、「はい」という単語が印刷されます。
test 15 -eq 15 && echo "はい"
test 14 -eq 15 && echo "はい"
単一ブラケットの条件付きテストは、 test
コマンドを模倣します。 式を角かっこ「 [ ]
」で囲み、 test
コマンドと同じように動作します。 実際、これらは同じプログラムであり、同じソースコードから作成されています。 唯一の操作上の違いは、 test
バージョンと[
バージョンがヘルプリクエストを処理する方法です。
これはソースコードからのものです:
/ * --helpまたは--versionを認識しますが、 "["形式、最後の引数が "]"でない場合。 直接使用 受け入れを回避するために、parse_long_optionsではなく解析 略語。 POSIXでは、「[-help」と「[--version」を次のように使用できます。 通常のGNU動作がありますが、「test--help」が必要です。 および「test--version」を使用して、ステータス0でサイレント終了します。* /
test
と[
に助けを求め、Bashに送信された応答コードを確認することで、この効果を確認できます。
test --help
エコー$?
[ - ヘルプ
エコー$?
test
と[
はどちらもシェルビルトインです。つまり、Bashに直接ベイクされます。 ただし、 [
のスタンドアロンバイナリバージョンもあります。
タイプテスト
タイプ [
whereis [
対照的に、二重括弧の条件付きテスト[[
および]]
はキーワードです。 [[
および]]
も論理テストを実行しますが、構文は異なります。 それらはキーワードであるため、シングルブラケットバージョンでは機能しないいくつかの優れた機能を使用できます。
二重角かっこキーワードはBashでサポートされていますが、他のすべてのシェルで使用できるわけではありません。 たとえば、Kornシェルはそれらをサポートしますが、プレーンな古いシェルshはサポートしません。 すべてのスクリプトは次の行で始まります。
#!/ bin / bash
これにより、スクリプトを実行するためにBashシェルを呼び出すことが保証されます。
関連: Windows10でBashシェルスクリプトを作成して実行する方法
ビルトインとキーワード
compgen
プログラムを使用して、ビルトインを一覧表示できます。
compgen -b | fmt -w 70
fmt
を介して出力をパイプ処理しないと、それぞれが独自の行に組み込まれている長いリストが得られます。 この場合、ビルトインが1つの段落にグループ化されているのを確認すると便利です。
test
と[
リストに]が表示されていますが、 ]
はリストされていません。 [
コマンドは、式の終わりに到達したことを検出するために終了]
を探しますが、 ]
は別個の組み込みではありません。 これは、パラメータリストの終わりを示すために[
に与える信号にすぎません。
キーワードを表示するには、次を使用できます。
compgen -k | fmt -w 70
[[
と]]
キーワードは両方ともリストに含まれています。これは、 [[
は1つのキーワードであり、 ]]
は別のキーワードであるためです。 それらは、 if
とfi
、 case
とesac
のように、一致するペアです。
Bashがスクリプト(またはコマンドライン)を解析していて、一致する終了キーワードを持つキーワードを検出すると、Bashはそれらの間に表示されるすべてのものを収集し、キーワードがサポートする特別な処理を適用します。
ビルトインを使用すると、ビルトインコマンドに続くものは、他のコマンドラインプログラムのパラメーターとまったく同じように渡されます。 これは、変数値のスペースなどに関して、スクリプトの作成者が特別な注意を払う必要があることを意味します。
シェルグロブ
ダブルブラケット条件付きテストでは、シェルグロブを利用できます。 これは、アスタリスク「 *
」が「何でも」を意味するように展開されることを意味します。
次のテキストをエディタに入力またはコピーして、「whelkie.sh」というファイルに保存します。
#!/ bin / bash stringvar = "Whelkie Brookes" if [["$ stringvar" == * elk *]]; それから echo「警告にはシーフードが含まれています」 それ以外 エコー「軟体動物を含まない」 fi
スクリプトを実行可能にするには、 -x
(実行)オプションを指定してchmod
コマンドを使用する必要があります。 試してみたい場合は、この記事のすべてのスクリプトに対してこれを行う必要があります。
chmod + x whelkie.sh
スクリプトを実行すると、文字列「elk」が文字列「Whelkie」で検出されたことがわかります。これは、他の文字で囲まれているかどうかに関係ありません。
./whelkie.sh
注意すべき点の1つは、検索文字列を二重引用符で囲まないことです。 そうした場合、グロブは発生しません。 検索文字列は文字通りに扱われます。
他の形式のシェルグロブが許可されます。 疑問符「 ?
」は単一の文字に一致し、単一の角括弧は文字の範囲を示すために使用されます。 たとえば、どちらのケースを使用するかわからない場合は、両方の不測の事態を範囲でカバーできます。
#!/ bin / bash stringvar = "Jean-Claude van Clam" if [["$ stringvar" == * [cC] lam *]]; それから echo「警告にはシーフードが含まれています。」 それ以外 エコー「軟体動物から解放されました。」 fi
このスクリプトを「damme.sh」として保存し、実行可能にします。 これを実行すると、条件ステートメントがtrueに解決され、ifステートメントの最初の句が実行されます。
./damme.sh
文字列の引用
文字列を二重引用符で囲むことについては前に説明しました。 そうした場合、シェルのグロブは発生しません。 慣例では良い習慣とされていますが、 [[
および]]
を使用する場合は、スペースが含まれている場合でも、文字列変数を引用符で囲む必要はありません。 次の例を見てください。 $stringvar
変数と$surname
文字列変数の両方にスペースが含まれていますが、条件ステートメントではどちらも引用符で囲まれていません。
#!/ bin / bash stringvar = "van Damme" surname = "van Damme" if [[$ stringvar == $ surname]]; それから echo "名前が一致します。" それ以外 echo "名前が一致しません。" fi
これを「surname.sh」というファイルに保存して実行可能にします。 以下を使用して実行します。
./surname.sh
両方の文字列にスペースが含まれているにもかかわらず、スクリプトは成功し、条件ステートメントはtrueに解決されます。 これは、スペースを含むパスとディレクトリ名を処理するときに役立ちます。 ここで、変数に有効なディレクトリ名が含まれている場合、 -d
オプションはtrueを返します。
#!/ bin / bash dir = "/ home / dave / Documents / Needs Work" if [[-d $ {dir}]]; それから エコー「ディレクトリ確認済み」 それ以外 エコー「ディレクトリが見つかりません」 fi
自分のコンピュータのディレクトリを反映するようにスクリプトのパスを変更し、テキストを「dir.sh」というファイルに保存して実行可能にすると、これが機能することがわかります。
./dir.sh
関連: Bashで変数を操作する方法
ファイル名GlobbingGotchas
[ ]
と[[ ]]
の興味深い違いは、グロブが含まれるファイル名に関連しています。 「* .sh」の形式は、すべてのスクリプトファイルに一致します。 単一のスクリプトファイルがない限り、単一の角かっこ[ ]
の使用は失敗します。 複数のスクリプトを検索すると、エラーがスローされます。
これは、単一括弧の条件付きのスクリプトです。
#!/ bin / bash if [-a * .sh]; それから echo "スクリプトファイルが見つかりました" それ以外 echo "スクリプトファイルが見つかりませんでした" fi
このテキストを「script.sh」に保存して実行可能にしました。 ディレクトリにあるスクリプトの数を確認してから、スクリプトを実行しました。
ls
./script.sh
Bashはエラーをスローします。 1つを除くすべてのスクリプトファイルを削除して、スクリプトを再度実行しました。
ls
./script.sh
条件付きテストはtrueを返し、スクリプトはエラーを引き起こしません。 二重角かっこを使用するようにスクリプトを編集すると、3番目のタイプの動作が提供されます。
#!/ bin / bash if [[-a * .sh]]; それから echo "スクリプトファイルが見つかりました" それ以外 echo "スクリプトファイルが見つかりませんでした" fi
これを「dscript.sh」というファイルに保存して実行可能にしました。 多くのスクリプトが含まれているディレクトリでこのスクリプトを実行してもエラーは発生しませんが、スクリプトはスクリプトファイルを認識できません。
二重括弧を使用した条件文は、ディレクトリに実際に「* .sh」というファイルがあるというまれなケースでのみtrueに解決されます。
./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
スクリプトは期待どおりに実行されます。
今回は||
を使用しますオペレーター。 10は15より大きくないが、25は26未満であるため、条件ステートメントはtrueに解決されます。最初の比較または2番目の比較のいずれかが真である限り、条件ステートメントは全体としてtrueに解決されます。
このテキストを「or.sh」として保存し、実行可能にします。
#!/ bin / bash 最初= 10 秒= 25 if [[first -gt 15 || 少尉26]]; それから echo「条件が満たされました。」 それ以外 echo "条件が失敗しました。" fi
./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
正規表現が数字を探しているが、 $words
文字列変数に保持されている値に数字がないため、最初の条件付きステートメントは失敗します。
$WordsandNumbers
文字列変数に数字が含まれているため、2番目の条件付きステートメントは成功します。
電子メールアドレスが適切にフォーマットされているため、最後の条件ステートメントは成功します。つまり、trueに解決されます。
たった1つの条件
ダブルブラケット条件付きテストは、スクリプトに柔軟性と読みやすさをもたらします。 条件付きテストで正規表現を使用できることは、 [[
および]]
の使用方法を学ぶことを正当化します。
スクリプトがBashのようにそれらをサポートするシェルを呼び出すことを確認してください。
関連: Bashで知っておく必要のある15の特殊文字