Оператор case в Bash
Оператор case bash обычно используется для упрощения сложных условных выражений, когда у вас есть несколько разных вариантов. Использование оператора case вместо вложенных операторов if поможет вам сделать ваши сценарии bash более читабельными и простыми в обслуживании.
Оператор case Bash имеет аналогичную концепцию с оператором switch Javascript или C. Основное отличие состоит в том, что в отличие от оператора C switch оператор case в Bash не продолжает поиск совпадения с шаблоном после того, как он нашел один и выполнил операторы, связанные с этим шаблоном.
В этом руководстве мы рассмотрим основы оператора case в Bash и покажем вам, как использовать его в сценариях оболочки.
синтаксис оператора case
Оператор case Bash имеет следующую форму:
case EXPRESSION in PATTERN_1) STATEMENTS ;; PATTERN_2) STATEMENTS ;; PATTERN_N) STATEMENTS ;; *) STATEMENTS ;; esac
- Каждый оператор case начинается с ключевого слова case , за которым следует выражение case и ключевое слово in . Заявление заканчивается esac словом esac .
- Вы можете использовать несколько шаблонов, разделенных | оператор. Оператор ) завершает список шаблонов.
- В шаблоне могут быть специальные символы .
- Шаблон и связанные с ним команды известны как предложение.
- Каждое предложение должно заканчиваться символом ;; .
- Выполняются команды, соответствующие первому шаблону, соответствующему выражению.
- Обычной практикой является использование подстановочного знака звездочки ( * ) в качестве последнего шаблона для определения регистра по умолчанию. Этот шаблон всегда будет совпадать.
- Если шаблон не найден, статус возврата равен нулю. В противном случае статус возврата — это статус завершения выполненных команд.
Пример заявления case
Вот пример использования оператора case в сценарии bash, который будет печатать официальный язык данной страны:
#!/bin/bash echo -n "Enter the name of a country: " read COUNTRY echo -n "The official language of $COUNTRY is " case $COUNTRY in Lithuania) echo -n "Lithuanian" ;; Romania | Moldova) echo -n "Romanian" ;; Italy | "San Marino" | Switzerland | "Vatican City") echo -n "Italian" ;; *) echo -n "unknown" ;; esac
Сохраните настраиваемый сценарий как файл и запустите его из командной строки.
Скрипт попросит вас ввести страну. Например, если вы наберете «Литва», он будет соответствовать первому шаблону, и будет выполнена команда echo в этом предложении.
Сценарий напечатает следующий вывод:
Enter the name of a country: Lithuania The official language of Lithuania is Lithuanian
Если вы введете страну, которая не соответствует никакому другому шаблону, кроме подстановочного знака звездочки по умолчанию, скажем, Аргентины, сценарий выполнит команду echo внутри предложения по умолчанию.
Enter the name of a country: Argentina The official language of Argentina is unknown
Выводы
К настоящему времени вы должны хорошо понимать, как писать операторы case bash. Они часто используются для передачи параметров сценарию оболочки из командной строки. Например, сценарии инициализации используют операторы case для запуска, остановки или перезапуска служб.
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
Linux shell case in
Инструкции case и select технически не являются циклами, поскольку не предусматривают многократное исполнение блока кода. Однако, они, как и циклы, управляют ходом исполнения программы, в зависимости от начальных или конечных условий.
case (in) / esac Конструкция case эквивалентна конструкции switch в языке C/C++. Она позволяет выполнять тот или иной участок кода, в зависимости от результатов проверки условий. Она является, своего рода, краткой формой записи большого количества операторов if/then/else и может быть неплохим инструментом при создании разного рода меню. case «$ variable» in
- Заключать переменные в кавычки необязательно, поскольку здесь не производится разбиения на отдельные слова.
- Каждая строка с условием должна завершаться правой (закрывающей) круглой скобкой ) .
- Каждый блок команд, отрабатывающих по заданному условию, должен завершаться двумя символами точка-с-запятой ;; .
- Блок case должен завершаться ключевым словом esac ( case записанное в обратном порядке).
Пример 10-24. Использование case
#!/bin/bash echo; echo "Нажмите клавишу и затем клавишу Return." read Keypress case "$Keypress" in [a-z] ) echo "буква в нижнем регистре";; [A-Z] ) echo "Буква в верхнем регистре";; 2 ) echo "Цифра";; * ) echo "Знак пунктуации, пробел или что-то другое";; esac # Допускается указыватль диапазоны символов в [квадратных скобках]. # Упражнение: # -------- # Сейчас сценарий считывает нажатую клавишу и завершается. # Измените его так, чтобы сценарий продолжал отвечать на нажатия клавиш, # но завершался бы только после ввода символа "X". # Подсказка: заключите все в цикл "while". exit 0
Пример 10-25. Создание меню с помощью case
#!/bin/bash # Грубый пример базы данных clear # Очистка экрана echo " Список" echo " ------" echo "Выберите интересующую Вас персону:" echo echo "[E]vans, Roland" echo "[J]ones, Mildred" echo "[S]mith, Julie" echo "[Z]ane, Morris" echo read person case "$person" in # Обратите внимание: переменная взята в кавычки. "E" | "e" ) # Пользователь может ввести как заглавную, так и строчную букву. echo echo "Roland Evans" echo "4321 Floppy Dr." echo "Hardscrabble, CO 80753" echo "(303) 734-9874" echo "(303) 734-9892 fax" echo "revans@zzy.net" echo "Старый друг и партнер по бизнесу" ;; # Обратите внимание: блок кода, анализирующий конкретный выбор, завершается # двумя символами "точка-с-запятой". "J" | "j" ) echo echo "Mildred Jones" echo "249 E. 7th St., Apt. 19" echo "New York, NY 10009" echo "(212) 533-2814" echo "(212) 533-9972 fax" echo "milliej@loisaida.com" echo "Подружка" echo "День рождения: 11 февраля" ;; # Информация о Smith и Zane будет добавлена позднее. * ) # Выбор по-умолчанию. # "Пустой" ввод тоже обрабатывается здесь. echo echo "Нет данных." ;; esac echo # Упражнение: # -------- # Измените этот сценарий таким образом, чтобы он не завершал работу #+ после вывода информации о персоне, а переходил на ожидание нового #+ ввода от пользователя. exit 0
Очень хороший пример использования case для анализа аргументов, переданных из командной строки.
#! /bin/bash case "$1" in "") echo "Порядок использования: $ "; exit 65;; # Параметры командной строки отсутствуют, # или первый параметр -- "пустой". # Обратите внимание на $ это подстановка параметра $. В результате получается $0. -*) FILENAME=./$1;; # Если имя файла (аргумент $1) начинается с "-", # то заменить его на ./$1 # тогда параметр не будет восприниматься как ключ команды. * ) FILENAME=$1;; # В противном случае -- $1. esac
Пример 10-26. Оператор case допускает использовать подстановку команд вместо анализируемой переменной
#!/bin/bash # Подстановка команд в "case". case $( arch ) in # команда "arch" возвращает строку, описывающую аппаратную апхитектуру. i386 ) echo "Машина на базе процессора 80386";; i486 ) echo "Машина на базе процессора 80486";; i586 ) echo "Машина на базе процессора Pentium";; i686 ) echo "Машина на базе процессора Pentium2 или выше";; * ) echo "Машина на другом типе процессора";; esac exit 0
Оператор case допускает использование шаблонных конструкций.
Пример 10-27. Простой пример сравнения строк
#!/bin/bash # match-string.sh: простое сравнение строк match_string () < MATCH=0 NOMATCH=90 PARAMS=2 # Функция требует два входных аргумента. BAD_PARAMS=91 [ $# -eq $PARAMS ] || return $BAD_PARAMS case "$1" in "$2") return $MATCH;; * ) return $NOMATCH;; esac >a=one b=two c=three d=two match_string $a # неверное число аргументов echo $? # 91 match_string $a $b # не равны echo $? # 90 match_string $b $d # равны echo $? # 0 exit 0
Пример 10-28. Проверка ввода
#!/bin/bash # isalpha.sh: Использование "case" для анализа строк. SUCCESS=0 FAILURE=-1 isalpha () # Проверка - является ли первый символ строки символом алфавита. < if [ -z "$1" ] # Вызов функции без входного аргумента? then return $FAILURE fi case "$1" in [a-zA-Z]*) return $SUCCESS;; # Первый символ - буква? * ) return $FAILURE;; esac ># Сравните с функцией "isalpha ()" в языке C. isalpha2 () # Проверка - состоит ли вся строка только из символов алфавита. < [ $# -eq 1 ] || return $FAILURE case $1 in *[!a-zA-Z]*|"") return $FAILURE;; *) return $SUCCESS;; esac >isdigit () # Проверка - состоит ли вся строка только из цифр. < # Другими словами - является ли строка целым числом. [ $# -eq 1 ] || return $FAILURE case $1 in *[!0-9]*|"") return $FAILURE;; *) return $SUCCESS;; esac >check_var () # Интерфейс к isalpha < if isalpha "$@" then echo "\"$*\" начинается с алфавитного символа." if isalpha2 "$@" then # Дальнейшая проверка не имеет смысла, если первй символ не буква. echo "\"$*\" содержит только алфавитные символы." else echo "\"$*\" содержит по меньшей мере один не алфавитный символ." fi else echo "\"$*\" начинсется с не алфавитного символа ." # Если функция вызвана без входного параметра, #+ то считается, что строка содержит "не алфавитной" символ. fi echo >digit_check () # Интерфейс к isdigit (). < if isdigit "$@" then echo "\"$*\" содержит только цифры [0 - 9]." else echo "\"$*\" содержит по меньшей мере один не цифровой символ." fi echo >a=23skidoo b=H3llo c=-What? d=What? e=`echo $b` # Подстановка команды. f=AbcDef g=27234 h=27a34 i=27.34 check_var $a check_var $b check_var $c check_var $d check_var $e check_var $f check_var # Вызов без параметра, что произойдет? # digit_check $g digit_check $h digit_check $i exit 0 # Сценарий дополнен S.C. # Упражнение: # -------- # Напишите функцию 'isfloat ()', которая проверяла бы вещественные числа. # Подсказка: Эта функция подобна функции 'isdigit ()', #+ надо лишь добавить анализ наличия десятичной точки.
Оператор select был заимствован из Korn Shell, и является еще одним инструментом, используемым при создании меню.
Этот оператор предлагает пользователю выбрать один из представленных вариантов. Примечательно, что select по-умолчанию использует в качестве приглашения к вводу (prompt) — PS3 ( #? ), который легко изменить.
Пример 10-29. Создание меню с помощью select
#!/bin/bash PS3='Выберите ваш любимый овощ: ' # строка приглашения к вводу (prompt) echo select vegetable in "бобы" "морковь" "картофель" "лук" "брюква" do echo echo "Вы предпочитаете $vegetable." echo ";-))" echo break # если 'break' убрать, то получится бесконечный цикл. done exit 0
Если в операторе select список in list не задан, то в качестве списка будет использоваться список аргументов ( $@), передаваемый сценарию или функции.
Сравните это с поведением оператора цикла
в котором не задан список аргументов.
Пример 10-30. Создание меню с помощью select в функции
#!/bin/bash PS3='Выберите ваш любимый овощ: ' echo choice_of() < select vegetable # список выбора [in list] отсутствует, поэтому 'select' использует входные аргументы функции. do echo echo "Вы предпочитаете $vegetable." echo ";-))" echo break done >choice_of бобы рис морковь редис томат шпинат # $1 $2 $3 $4 $5 $6 # передача списка выбора в функцию choice_of() exit 0