Шрифт:
do
sleep 60
done
# Теперь звонит колокольчик и извещает о новом пользователе
echo -е '\а'
echo "**** $1 has just logged in ****"
exit 0
Если пользователь уже зарегистрировался в системе, выполнять цикл нет необходимости. Поэтому естественно выбрать цикл
until
, а не цикл while
. case
Оператор
case
немного сложнее уже рассмотренных нами операторов. У него следующая синтаксическая запись:
case переменная in
образец [ | образец] ...) операторы;;
образец [ | образец] ...) операторы;;
esac
Конструкция оператора
case
выглядит слегка устрашающей, но она позволяет довольно изощренным способом сопоставлять содержимое переменной с образцами и затем выполнять разные операторы в зависимости от того, с каким образцом найдено соответствие. Это гораздо проще, чем проверять несколько условий, применяемых во множественных операторах if
, elif
и else
. Примечание
Обратите внимание на то, что каждая ветвь с образцами завершается удвоенным символом "точка с запятой" (
;;
). В каждой ветви оператора case
можно поместить несколько операторов, поэтому сдвоенная точка с запятой необходима для отметки завершения очередного оператора и начала следующей ветви с новым образцом в операторе case
. Возможность сопоставлять многочисленные образцы и затем выполнять множественные связанные с образцом операторы делают конструкцию
case
очень удобной для обработки пользовательского ввода. Лучше всего увидеть, как работает конструкция case
на примерах. Мы будем применять ее в упражнениях 2.6–2.8, каждый раз совершенствуя сопоставление с образцами. Примечание
Применяя конструкцию
case
с метасимволами в образцах, такими как *
, будьте особенно внимательны. Проблема заключается в том, что принимается во внимание первое найденное соответствие образцу, несмотря на то, что в последующих ветвях могут быть образцы с более точным соответствием. Упражнение 2.6. Вариант 1: пользовательский ввод
Вы можете написать новую версию сценария проверки пользовательского ввода с помощью конструкции
case
, сделав сценарий немного более избирательным и терпимым к неожиданным вариантам ввода.
#!/bin/sh
echo "Is it morning? Please answer yes or no "
read timeofday
case "$timeofday" in
yes) echo "Good Morning";;
no ) echo "Good Afternoon";;
y ) echo "Good Morning";;
n ) echo "Good Afternoon";;
* ) echo "Sorry, answer not recognized";;
esac
exit 0
Как это работает
Когда выполняется оператор
case
, он берет содержимое переменной timeofday
и сравнивает его поочередно с каждой строкой-образцом. Как только строка совпадает с введенной информацией, оператор case
выполняет код, следующий за )
, и завершается. Оператор
case
выполняет обычную подстановку в строках, которые он использует для сравнения. Следовательно, вы можете задать часть строки с последующим метасимволом *
. Применение единственного символа *
будет соответствовать совпадению с любой введенной строкой, поэтому поместите этот вариант после всех остальных образцов строк для того, чтобы задать некоторое стандартное поведение оператора case
, если не будут найдены совпадения с другими строками-образцами. Это возможно, потому что оператор case
сравнивает с каждой строкой-образцом поочередно. Он не ищет наилучшее соответствие, а всего лишь первое встретившееся. Условие, принятое по умолчанию, часто оказывается невыполнимым, поэтому применение метасимвола *
может помочь в отладке сценариев. Упражнение 2.7. Вариант 3: объединение образцов
Предыдущая версия конструкции case, безусловно, элегантнее варианта с множественными операторами
if
, но, объединив все образцы, можно создать более красивую версию.
#!/bin/sh
echo "Is it morning? Please answer yes or no "
read timeofday
case "$timeofday" in
yes | y | Yes | YES ) echo "Good Morning";;