Bash スクリプトの 2 つのメニュー選択

Bash スクリプトの 2 つのメニュー選択

私はBashを学習しており、演習問題を解こうとしています。

この演習では、メニュー リストから姓と名を選択します。ただし、名前がリストにない場合は、手動入力を設定します。

しかし、オプションを選択したときに、Quit オプションを選択せず​​に 2 番目のメニューに移動する方法がわからないため、少し混乱しています (任意のオプションに Break を追加しようとしましたが、機能しません)。

手動入力の場合、ユーザーからの入力を読み取ってみましたが、機能していないようです。何か提案はありますか?

名前と姓を取得したときにループを終了するにはどうすればよいですか? 両方を取得すると、同じループになるからです。

echo -e "Choose your name Exercise #2 \n"
PS3='Please enter your name from the List: '
options=("Elvis" "John" "Mark" "Manual Input" "Quit")
select opt in "${options[@]}"
do
    case $opt in
        "Option 1")
            ;;
        "Option 2")
            ;;
        "Option 3")
            ;;
        "Option 4")
            echo "Sorry your Name is not in the List Give your name"
            read -e -p "Whats your name: " MANUALINPUT
            ;;
        "Quit")
            break
            ;;
   esac

echo "Hello $opt Next Step is Select your Lastname "
done

PS4='Please enter your last name from the List: '
options2=("Smith" "Brown" "Miller" "Manual Input" "Quit")
select opt2 in "${options2[@]}"
do
    case $opt2 in
        "Option 1")
            ;;
        "Option 2")
            ;;
        "Option 3")
            ;;
        "Option 4")
            echo "Sorry your Name is not in the List Give your name"
            read -e -p "Whats your name: " MANUALINPUT
            ;;
        "Quit")
            break
            ;;
   esac

clear
echo "Welcome $opt $opt2"
done

答え1

ループはユーザーが選択したオプションにselect設定され、 はユーザーが入力した内容に設定されます。したがって、ユーザーが最初の質問への応答として と入力した場合、 は になり、になります。 はどの時点でもになりません。よりもテスト用のステートメントを記述しやすくなります。opt$REPLY1$REPLY1$optElvis$optOption 1case$REPLY$opt

また、名前で挨拶するのはまだ早いです内部ループの終わりからループの終わりまでの間のselectコードは、ユーザーがcasedoneselect無効メニューから選択します (*)ケース ラベルを使用してこれを行うこともできます)。

nameやのような、より説明的な変数名を使用する方が適切でありfamily、オプションを格納するために 2 つの別々の配列は必要ありません (実際、文字列を直接リストできるため、この場合は配列が必要かどうかは疑問です)。

以下のコードでは、exitユーザーが を選択した場合にコードを終了するようにしていますQuit(はループbreakを終了しselect、ユーザーが名前を正常に選択したときにこれを使用します)。すべての対話型ダイアログは、通常どおり標準エラー ストリームで発生します。

#!/bin/bash

PS3='Please enter your name from the list: '
options=("Elvis" "John" "Mark" "Manual input" "Quit")
select name in "${options[@]}"; do
    case $REPLY in
        1|2|3)
            break       # user picked name from list
            ;;
        4)
            echo 'Sorry your name is not in the list' >&2
            read -e -r -p "What's your name: " name
            break
            ;;
        5)
            echo 'Bye!' >&2
            exit
            ;;
   esac

   echo 'Try again!' >&2

done
printf 'Hello %s, now select your family name\n' "$name" >&2

PS3='Please enter your family name from the list: '
options=("Smith" "Brown" "Miller" "Manual input" "Quit")
select family in "${options[@]}"; do
    case $REPLY in
        1|2|3)
            break       # user picked name from list
            ;;
        4)
            echo 'Sorry your family is not in the list' >&2
            read -e -r -p "What's your family: " family
            ;;
        5)
            echo 'Bye!' >&2
            exit
            ;;
    esac

    echo 'Try again!' >&2

done

printf 'Welcome, %s %s!\n' "$name" "$family"

その他の小さな点も修正されました:バックスラッシュを正しく読み取れるように-rwith を使用し、 2 番目のループで選択プロンプトを設定するためにの代わりにを使用しました。readPS4PS3

関連情報