導入
if・elif・elif… と3段4段に伸びてきたら、case の出番です。「この値だったらこれ」という分岐は、case のほうが圧倒的に読みやすく、パターン(*.txt のような書き方)も使えます。
説明
case は、1つの値をいくつものパターンと照合します。
#!/bin/bash
action=$1
case "$action" in
start)
echo "サービスを起動します"
;;
stop)
echo "サービスを停止します"
;;
restart|reload)
echo "サービスを再起動します"
;;
*)
echo "使い方: sh script.sh {start|stop|restart}"
;;
esac
読み方はこうです。
パターン)… このパターンに一致したら、次の;;までを実行する;;… その枝の終わり(忘れやすい)restart|reload…|で複数のパターンをまとめられる*)… どれにも当てはまらないとき(他の言語の default)esac… 終わり(case の逆さま)
パターンにはワイルドカードが使えます。ここが if との大きな違いです。
case "$file" in
*.txt) echo "テキストファイル" ;;
*.log) echo "ログファイル" ;;
*.tar.gz) echo "圧縮ファイル" ;;
*) echo "不明な種類" ;;
esac
flowchart TD
A["case \"$action\" in"] --> B{"start ?"}
B -->|"一致"| C["起動処理 → ;;"]
B -->|"不一致"| D{"stop ?"}
D -->|"一致"| E["停止処理 → ;;"]
D -->|"不一致"| F{"restart / reload ?"}
F -->|"一致"| G["再起動処理 → ;;"]
F -->|"不一致"| H["*) 使い方を表示"]
systemctl start nginx のような「サブコマンドを取るツール」は、中身がまさにこの形をしています。自分のスクリプトにも start / stop / status を持たせると、一気に道具らしくなります。
やってみよう
端末で sh script.sh start、sh script.sh stop、sh script.sh reload、そして引数なしの sh script.sh を順に実行してください。それぞれ別の枝に落ちること、引数なしでは *) の使い方表示になることを確かめましょう。
演習
sh script.sh restart を実行して、サービスを再起動します と表示させてください。
ヒント1を見る
restart|reload) の枝に入る引数を渡します。
ヒント2を見る
下の端末で sh script.sh restart