技術ノート Linux Bash スクリプトで Case ステートメントを使用する方法

Bash スクリプトで Case ステートメントを使用する方法

重要なポイント

  • Bash case ステートメントを使用すると、長い if-then-else ステートメントに比べてスクリプトの読み取りと保守が容易になります。
  • Bash の case ステートメントは、句内のパターンを持つ式と一致し、それに応じてステートメントを実行します。
  • 1 つの句で複数のパターンを使用できるため、スクリプトがより簡潔かつ効率的になります。 case ステートメントでは、数字または数値変数も使用できます。

Bash case ステートメントは強力でありながら、簡単に作成できます。古い Linux スクリプトを再検討すると、長い if-then-else ステートメントの代わりに case ステートメントを使用したことに満足するでしょう。

事件の声明

ほとんどのプログラミング言語には、switch または case ステートメントのバージョンがあります。これらは、変数の値に従ってプログラムの実行フローを指示します。通常、変数の予想される値のそれぞれに対して定義された実行ブランチがあり、他のすべての値に対して 1 つのキャッチオールまたはデフォルト ブランチが存在します。

論理機能は、 if ステートメント の 1 つで以前に処理されなかったすべてのものをキャッチする else ステートメントを備えた、if-then ステートメントの長いシーケンスに似ています。

case の 実装は、式を句の 1 つと照合しようとします。これは、各句を順番に調べて、一致するパターンを見つけようとすることによって行われます。句内のパターンは文字列ですが、直観に反しますが、それは式として数値を使用できないという意味ではありません。

Bash スクリプトで Case ステートメントを使用する方法

一般的なケース

case ステートメントの一般的な形式は次のとおりです。

 case expression in

pattern-1)
statement
;;

pattern-2)
statement
;;
.
.
.

pattern-N)
statement
;;

*)
statement
;;
esac

  • case ステートメントは、case キーワードで始まり、 esac キーワードで終わる必要があります。
  • 式は評価され、一致するものが見つかるまで各句のパターンと比較されます。
  • 一致する句内の 1 つまたは複数のステートメントが実行されます。
  • 二重セミコロン「 ;; 」は句を終了するために使用されます。
  • パターンが一致し、その句内のステートメントが実行された場合、他のすべてのパターンは無視されます。
  • 条項の数に制限はありません。
  • アスタリスク「 * 」はデフォルトのパターンを示します。式が case ステートメント内の他のパタ​​ーンのいずれとも一致しない場合は、default 句が実行されます。
Bash スクリプトで Case ステートメントを使用する方法

簡単な例

このスクリプトは、架空の店の営業時間を示します。 +"%a" 形式文字列を指定した date コマンドを使用して、短縮された日の名前を取得します。これは DayName 変数に保存されます。

 #!/bin/bash

DayName=$(date + "%a" )

echo "Opening hours for $DayName "

case $DayName in

Mon)
echo "09:00 - 17:30"
;;

Tue)
echo "09:00 - 17:30"
;;

Wed)
echo "09:00 - 12:30"
;;

Thu)
echo "09:00 - 17:30"
;;

Fri)
echo "09:00 - 16:00"
;;

Sat)
echo "09:30 - 16:00"
;;

Sun)
echo "Closed all day"
;;

*)
;;
esac

そのテキストをエディタにコピーし、「open.sh」という名前のファイルとして保存します。

chmod コマンドを使用して 実行可能にする必要があります。この記事を進める際には、作成するすべてのスクリプトに対してこれを行う必要があります。

 chmod +x open.sh

これでスクリプトを実行できるようになりました。

 ./open.sh

スクリーンショットが撮影された日はたまたま金曜日でした。つまり、DayName 変数には文字列「Fri」が保持されます。これは、「Fri)」句の「Fri」パターンと一致します。

句内のパターンを二重引用符で囲む必要はありませんが、二重引用符で囲んでも問題はありません。ただし、パターンにスペースが含まれる場合は二重引用符を使用する必要があります。

デフォルト句は空のままになっています。前述の節のいずれかに一致しないものは無視されます。

このスクリプトは機能しており、読みやすいですが、冗長で繰り返しが多いです。この種の case ステートメントは非常に簡単に短縮できます。

Bash スクリプトで Case ステートメントを使用する方法

句内での複数のパターンの使用

case ステートメントの非常に優れた機能は、各句で複数のパターンを使用できることです。式がこれらのパターンのいずれかに一致する場合、その節内のステートメントが実行されます。

これは、1 か月に何日あるかを示すスクリプトです。答えは 3 つだけです。2 月は 30 日、31 日、または 28 日または 29 日です。したがって、12 か月ありますが、必要な条項は 3 つだけです。

このスクリプトでは、ユーザーは月の名前の入力を求められます。パターンマッチングで大文字と小文字を区別しないようにするには、shopt コマンドに「-s nocasematch」オプションを付けて使用します。入力に大文字、小文字、またはその 2 つの混合が含まれているかどうかは関係ありません。

 #!/bin/bash

shopt -s nocasematch

echo "Enter name of a month"
read month

case $month in

February)
echo "28/29 days in $month "
;;

April | June | September | November)
echo "30 days in $month "
;;

January | March | May | July | August | October | December)
echo "31 days in $month "
;;

*)
echo "Unknown month: $month "
;;
esac

2 月にはそれ自体に条項があり、他のすべての月は、30 日か 31 日かどうかに応じて 2 つの条項を共有します。マルチパターン句ではパイプ記号「|」を使用します。セパレータとして。デフォルトのケースでは、スペルが間違っている月も検出されます。

これを「month.sh」というファイルに保存し、実行可能にしました。

 chmod +x month.sh

スクリプトを数回実行して、大文字と小文字のどちらを使用しても問題がないことを示します。

 ./month.sh

大文字と小文字の違いを無視するようにスクリプトに指示したため、正しく綴られた月名は 3 つの主要句のいずれかによって処理されます。月の綴りが間違っている場合は、default 句によって検出されます。

Bash スクリプトで Case ステートメントを使用する方法

数字の使用 In case ステートメント

式として数字や数値変数を使用することもできます。このスクリプトは、ユーザーに 1 ~ 3 の範囲の数値を入力するように求めます。各句のパターンが文字列であることを明確にするために、二重引用符で囲まれています。それにもかかわらず、スクリプトはユーザーの入力を適切な句と照合します。

 #!/bin/bash

echo "Enter 1, 2, or 3: "
read Number

case $ Number in

"1" )
echo "Clause 1 matched"
;;

"2" )
echo "Clause 2 matched"
;;

"3" )
echo "Clause 3 matched"
;;

*)
echo "Default clause matched"
;;
esac

 ./number.sh 

Bash スクリプトで Case ステートメントを使用する方法

for ループでの case ステートメントの使用

case ステートメントは、単一の式のパターン マッチを試みます。処理する式が多数ある場合は、for ループ内に case ステートメントを入れることができます。

このスクリプトは、 ls コマンド を実行してファイルのリストを取得します。 for ループでは、ファイルのグロビング ( 正規表現 とは似ていますが、異なります) が各ファイルに順番に適用され、ファイル拡張子が抽出されます。これは拡張文字列変数に保存されます。

case ステートメントは、句との一致を試みる式として Extension 変数を使用します。

 #!/bin/bash

for File in $(ls)

do
# extract the file extension
Extension=${File ##*.}

case " $Extension " in

sh)
echo " Shell script: $File "
;;

md)
echo " Markdown file: $File "
;;

png)
echo "PNG image file: $File "
;;

*)
echo "Unknown: $File "
;;
esac
done

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

 ./ファイルタイプ.sh

私たちの最小限のファイルタイプ識別スクリプトは機能します。

Bash スクリプトで Case ステートメントを使用する方法

case ステートメントを使用した終了コードの処理

正常に動作するプログラムは、終了時に終了コードをシェルに送信します。従来のスキームでは、問題のない実行を示すために終了コード値 0 を使用し、さまざまなタイプのエラーを示すために 1 以上の値を使用します。

多くのプログラムは 0 と 1 だけを使用します。すべてのエラー条件を 1 つの終了コードにまとめると、問題の特定がより困難になりますが、これは一般的な方法です。

私たちは、ランダムに 0 または 1 の終了コードを返す「go-geek」と呼ばれる小さなプログラムを作成しました。次のスクリプトは go-geek を呼び出します。 $?を使用して終了コードを取得します。シェル変数を取得し、それを case ステートメントの式として使用します。

実際のスクリプトは、終了コードを生成したコマンドの成功または失敗に応じて適切な処理を実行します。

 
#!/bin/bash

go-geek

case $? in

"0" )
echo "Response was: Success"
echo "Do appropriate processing in here"
;;

"1" )
echo "Response was: Error"
echo "Do appropriate error handling in here"
;;

*)
echo "Unrecognised response: $?"
;;
esac

これを「return-code.sh」というスクリプトに保存し、実行可能にします。 go-geek コマンドを他のコマンドに置き換える必要があります。存在しないディレクトリに cd して終了コード 1 を取得し、スクリプトを編集してアクセス可能なディレクトリに cd して終了コード 0 を取得することができます。

スクリプトを数回実行すると、さまざまな終了コードが case ステートメントによって正しく識別されることがわかります。

 ./リターンコード.sh

可読性が保守性を高める

古い Bash スクリプトに戻って、そのスクリプトがどのように動作するかを理解することは、特に他の人によって書かれた場合には困難です。古いスクリプトの機能を修正するのはさらに困難です。

case ステートメントを使用すると、明確で簡単な構文でロジックを分岐できます。それは双方にとって有利です。

「 Bash スクリプトで Case ステートメントを使用する方法」に関するベスト動画選定!

【丁寧に学ぶLinux入門】 ⑥シェルスクリプト(.shファイル)
【Bシェル/bash入門】(7) case文 〜if文を使わない条件分岐〜