Читаем Основы программирования в Linux полностью

Примечание

Обратите внимание на то, что каждая ветвь с образцами завершается удвоенным символом "точка с запятой" (;;). В каждой ветви оператора 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";;

 n* | N*)              echo "Good Afternoon";;

 * )                   echo "Sorry, answer not recognized";;

esac


exit 0

Как это работает

Данный сценарий в операторе case использует несколько строк-образцов в каждой ветви, таким образом, case проверяет несколько разных строк для каждого возможного оператора. Этот прием делает сценарий короче и, как показывает практика, облегчает его чтение. Приведенный программный код также показывает, как можно использовать метасимвол *, несмотря на то, что он может соответствовать непредусмотренным образцам. Например, если пользователь введет строку never, она будет соответствовать образцу n*, и на экран будет выведено приветствие Good Afternoon (Добрый день), хотя такое поведение в сценарии не предусматривалось. Учтите также, что заключенный в кавычки знак подстановки * не действует.

Упражнение 2.8. Вариант 3: выполнение нескольких операторов

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже