シェルスクリプトでユーザからの入力を受け付け、複数の階層を持ったメニューを作る
readコマンドでユーザからの入力を受け付けてcase構文を用いてその内容を処理するという流れをシェルスクリプトの中で用いることで、ユーザからの入力を処理できる。
下は例。
#! /bin/sh show_mainmenu() { while true; do cat <<EOF メインメニュー 1:サブメニュー1 2:サブメニュー2 3:終了 数字を入力してください EOF # キー入力をACT_MAINに代入 read ACT_MAIN # キー入力された値によって分岐 case ${ACT_MAIN} in 1) show_submenu1 break ;; 2) show_submenu2 break ;; 3) break ;; *) printf "エラー: 無効な項目 \"%s\" が入力されました\n" "${ACT_MAIN}" ;; esac done } show_submenu1() { while true; do cat <<EOF サブメニュー1 1:メニュー項目1-1 2:メニュー項目1-2 3:メインメニューに戻る 数字を入力してください EOF read ACT_SUB1 case ${ACT_SUB1} in 1) echo "メニュー項目1-1が選択されました" break ;; 2) echo "メニュー項目1-2が選択されました" break ;; 3) show_mainmenu break ;; *) printf "エラー: 無効な項目 \"%s\" が入力されました\n" "${ACT_SUB1}" ;; esac done } show_submenu2() { while true; do cat <<EOF サブメニュー2 1:メニュー項目2-1 2:メニュー項目2-2 3:メインメニューに戻る 数字を入力してください EOF read ACT_SUB2 case ${ACT_SUB2} in 1) echo "メニュー項目2-1が選択されました" break ;; 2) echo "メニュー項目2-2が選択されました" break ;; 3) show_mainmenu break ;; *) printf "エラー: 無効な項目 \"%s\" が入力されました\n" "${ACT_SUB2}" ;; esac done } # ここから処理開始 show_mainmenu
これを実行すると
メインメニュー 1:サブメニュー1 2:サブメニュー2 3:終了 数字を入力してください
というメニューが出るので、それぞれの数字を入力してEnterを押す。「1」にすると
サブメニュー1 1:メニュー項目1-1 2:メニュー項目1-2 3:メインメニューに戻る 数字を入力してください
のようにサブメニューが表示され、次に選択した項目によって
メニュー項目1-1が選択されました
のようにメッセージが出力されて終了する。サブメニューで「3」を選択するとメインメニューに戻り、メインメニューで「3」を選択すると終了する。
無効な文字列を入力すると
エラー: 無効な項目 "foo" が入力されました
のように表示されて元の入力に戻る。
なお、無限ループの記述では、bashやzshでは
for ((;;)); do ... done
と書くこともできるが、シェル依存となるので、dashでも動作するように
while true; do ... done
とした。