Основы программирования в Linux
Упражнение 2.6. Вариант 1: пользовательский вводВы можете написать новую версию сценария проверки пользовательского ввода с помощью конструкции
, сделав сценарий немного более избирательным и терпимым к неожиданным вариантам ввода.case#!/bin/shecho "Is it morning? Please answer yes or no "read timeofdaycase "$timeofday" inyes) echo "Good Morning";;no ) echo "Good Afternoon";;y ) echo "Good Morning";;n ) echo "Good Afternoon";;* ) echo "Sorry, answer not recognized";;esacexit 0Как это работает
Когда выполняется оператор
, он берет содержимое переменнойcaseи сравнивает его поочередно с каждой строкой-образцом. Как только строка совпадает с введенной информацией, операторtimeofdayвыполняет код, следующий заcase, и завершается.)Оператор
выполняет обычную подстановку в строках, которые он использует для сравнения. Следовательно, вы можете задать часть строки с последующим метасимволомcase. Применение единственного символа*будет соответствовать совпадению с любой введенной строкой, поэтому поместите этот вариант после всех остальных образцов строк для того, чтобы задать некоторое стандартное поведение оператора*, если не будут найдены совпадения с другими строками-образцами. Это возможно, потому что операторcaseсравнивает с каждой строкой-образцом поочередно. Он не ищет наилучшее соответствие, а всего лишь первое встретившееся. Условие, принятое по умолчанию, часто оказывается невыполнимым, поэтому применение метасимволаcaseможет помочь в отладке сценариев.*Упражнение 2.7. Вариант 3: объединение образцовПредыдущая версия конструкции case, безусловно, элегантнее варианта с множественными операторами
, но, объединив все образцы, можно создать более красивую версию.if#!/bin/shecho "Is it morning? Please answer yes or no "read timeofday<i>case "$timeofday" in</i><i> yes | y | Yes | YES ) echo "Good Morning";;</i><i> n* | N*) echo "Good Afternoon";;</i><i> * ) echo "Sorry, answer not recognized";;</i><i>esac</i>exit 0Как это работает
Данный сценарий в операторе
использует несколько строк-образцов в каждой ветви, таким образом,caseпроверяет несколько разных строк для каждого возможного оператора. Этот прием делает сценарий короче и, как показывает практика, облегчает его чтение. Приведенный программный код также показывает, как можно использовать метасимволcase, несмотря на то, что он может соответствовать непредусмотренным образцам. Например, если пользователь введет строку*, она будет соответствовать образцуnever, и на экран будет выведено приветствие Good Afternoon (Добрый день), хотя такое поведение в сценарии не предусматривалось. Учтите также, что заключенный в кавычки знак подстановкиn*не действует.*Упражнение 2.8. Вариант 3: выполнение нескольких операторовВ заключение, для того чтобы сделать сценарий многократно используемым, вам необходимо использовать другое значение кода завершения в том случае, когда применяется образец по умолчанию для непонятного варианта ввода.
#!/bin/shecho "Is it -morning? Please answer yes or no"read timeofday<i>case "$timeofday" in</i><i> yes | y | Yes | YES )</i>
echo "Good Morning"<i> echo "Up bright and early this morning"</i><i> ;;</i><i> [nN]*)</i><i> echo "Good Afternoon"</i><i> ;;</i><i> *)</i><i> echo "Sorry, answer not recognized"</i><i> echo "Please answer yes or no"</i><i> exit 1</i><i> ;;</i><i>esac</i>exit 0Как это работает
Для демонстрации другого способа определения соответствия образцу в этом программном коде изменен вариант определения соответствия для ветви
. Также видно, как в каждой ветви оператора case может выполняться несколько операторов. Следует быть внимательным и располагать в операторе самые точные образцы строк первыми, а самые общие варианты образцов последними. Это очень важно, потому что операторnoвыполняется, как только найдено первое, а не наилучшее соответствие. Если вы поставите ветвьcaseпервой, совпадение с этим образцом будет определяться всегда, независимо от варианта введенной строки.*)ПримечаниеУчтите, что сдвоенная точка с запятой
перед служебным словом;;необязательна. В отличие от программирования на языке С, в котором пропуск маркера завершения считается плохим стилем программирования, пропускesacне создает проблем, если последняя ветвь оператора;;— это вариант, принятый по умолчанию, поскольку другие образцы уже не будут анализироваться.case