Оператори вибору

Конструкція case еквівалентна конструкції switch в мові C / C ++. Вона дозволяє виконувати ту чи іншу ділянку коду, в залежності від результатів перевірки умов. Вона є, свого роду, короткою формою запису великої кількості операторів if / then / else і може бути непоганим інструментом при створенні різного роду меню.

case "$ variable" in
"$ Condition1")
command ...
;;
"$ Condition2")
command ...
;;
esac


  • Укладати змінні в лапки необов'язково, оскільки тут не проводиться розбиття на окремі слова.

  • Кожен рядок з умовою повинна завершуватися правої (закриває) круглою дужкою).

  • Кожен блок команд, що відпрацьовують по заданій умові, повинен завершуватися двома символами точка-з-коми ;; .

  • Блок case повинен завершуватися ключовим словом esac (case записане в зворотному порядку).


Приклад 10-24. Використання case

#! / Bin / bash echo; echo "Натисніть, а потім потім клавішу Return." read Keypress case "$ Keypress" in [az]) echo "буква в нижньому регістрі" ;; [AZ]) echo "Буква в верхньому регістрі" ;; [0-9]) 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 "[email protected]" 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 "[email protected]" echo "Подружка" echo "ім`я місце жітельсва 11 лютого" ;; # Інформація про Smith і Zane буде додана пізніше. *) # Вибір за замовчуванням. # "Порожній" введення теж обробляється тут. echo echo "Немає даних." ;; esac echo # Вправа: # -------- # Змініть цей сценарій таким чином, щоб він не завершував роботу # + після виведення інформації про персону, а переходив на очікування нового # + введення від користувача. exit 0

Дуже хороший приклад використання case для аналізу аргументів, переданих з командного рядка.

#! / Bin / bash case "$ 1" in "") echo "Порядок використання: $ {0 ## * /} <filename>"; exit 65 ;; # Параметри командного рядка відсутні, # або перший параметр - "порожній". # Зверніть увагу на $ {0 ## * /} це підстановка параметра $ {var ## pattern}. В результаті виходить $ 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 "\" $ * \ "містить щонайменше один не цифровий символ.&quot; 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 # Сценарій доповнений SC # Вправа: # -------- # Напишіть функцію 'isfloat ()', яка перевіряла б речові числа. # Підказка: Ця функція подібна функції 'isdigit ()', # + треба лише додати аналіз наявності десяткового дробу.

Оператор select був запозичений з Korn Shell, і є ще одним інструментом, використовуваним при створенні меню.

select variable [in list]
do
command ...
break
done


Цей оператор пропонує користувачеві вибрати один з представлених варіантів. Примітно, що 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 не заданий, то в якості списку буде використовуватися список аргументів ($ @), який передається сценарієм або функції.

Порівняйте це з поведінкою оператора циклу

for variable [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

Див. також приклад 34-3 .

Match_string $ a $ b # нерівні echo $?
Match_string $ b $ d # рівні echo $?
If [-z "$ 1"] # Виклик функції без вхідного аргументу?
Then return $ FAILURE fi case "$ 1" in [a-zA-Z] *) return $ SUCCESS ;; # Перший символ - буква?
Quot; fi echo} a = 23skidoo b = H3llo c = -What?
D = What?
Check_var $ a check_var $ b check_var $ c check_var $ d check_var $ e check_var $ f check_var # Виклик без параметра, що станеться?