Я изучаю Bash и пытаюсь решить упражнение.
Упражнение состоит из выбора имени и фамилии из списка меню. Однако, если имени нет в списке, установите ручной ввод.
Но я немного запутался, потому что я не знаю, как перейти во второе меню, когда есть опция «Выход» (я пытаюсь добавить «Перерыв» в любую опцию, но это не работает).
Для ручного ввода попробуйте прочитать ввод пользователя, но не видите никаких рабочих предложений?
Как мне завершить цикл, когда я получаю имя и фамилию? Потому что когда я получаю и то, и другое, я попадаю в тот же цикл.
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
на выбранный пользователем вариант, и он будет установлен $REPLY
на то, что пользователь ввел. Так что если пользователь ввел 1
в ответ на ваш первый вопрос, $REPLY
будет 1
и $opt
будет Elvis
. Ни в коем случае не $opt
будет Option 1
. Это упрощает написание ваших case
утверждений для тестирования $REPLY
, а не $opt
.
Также еще слишком рано приветствовать человека по имени.внутрицикл select
, поскольку мы все еще не уверены, что у нас есть настоящее имя для них. Код между концом оператора case
и done
циклом select
запускается, когда пользователь выбираетневерныйвыбор из меню (то же самое можно сделать с помощью *)
этикетки кейса).
Было бы лучше использовать более описательные имена переменных, например name
и family
, и нам не нужны два отдельных массива для хранения параметров (на самом деле, сомнительно, нужны ли вообще массивы в этом случае, поскольку мы могли бы перечислить строки напрямую).
В коде ниже я также сделал так, чтобы код завершался, 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"
Исправлены другие мелкие ошибки: для правильного чтения обратных косых черт используется -r
with , а для настройки приглашения к выбору во втором цикле используется instead .read
PS4
PS3