Оператор case в bash

case - оператор для множественного ветвления, заменяющий цепочки операторов if/then/else.

Пример:

case "$var" in
	yes ) echo "glad u agreed" ;;
	no )
		echo "sorry; good bye"
		exit
	;;
	* ) echo "Invalid answer. try again" ;;
esac

Круглые скобки в case

Для каждой закрывающей скобки в синтаксисе case есть возможность поставить открывающую круглую скобку: (“yes”) вместо “yes”) в примере выше.
Ставить открывающую скобку необязательно + зачем лишний символ?

Мощь case в поддержке сопоставления с шаблонами (это также и идиоматический подход):

case "$var" in
	[Nn][Oo]* )    # здесь, как вариант, писать комменты
		echo "Нет, так, нет"
		exit
	;;
	[Yy]?? | [Ss]ure | [Oo][Kk]* )
		echo "Ok, glad we agree"
	;;
	* ) echo "Try again"
		continue
	;;
esac
 
# Оператор case в bash
last | latest) some_cmd ;;
 
# пример простой документации:
index )     # Комментарий
	# Пример:
		# какой-нибудь пример
		# примеррррр
	some_cmd --some-arg
;;

В примере выше использовал подстановочные знаки командной строки, которые обычно используются при передаче filenames. Есть три подстановочных знака:

  • ? - любой символ
  • * - любые символы
  • [ ] - любой из символов внутри них

Из примера выше:
Конструкция [Nn][Oo]* соответствует, например: no, nO, NO, noway, Not Ever .
Вертикальная черта ( | ) - это, по сути, логическое “ИЛИ”, то есть, шаблону [Yy]?? | [Ss]ure | [Oo][Kk]* будут соответствовать: Yes, yes, YES, yEs, yES, yup, Sure, sure, OK, ok, OKfine, OK why not.

* )- это вариант по умолчанию, то есть, шаблон, совпадающий с чем угодно. Если ни с одним из предыдущих шаблонов совпадений не было найдено - с этим найдется всегда. Поэтому его и помещают последним в списке.

Советы,-примечания,-сценарии-использования-для-bash#шаблоны---это-не-regex

Короче, если нужны RegEx-ы - используй if/then/else конструкцию, а не case.

Про символы ;;

Символы ;; означают, что ничего дальше не нужно делать, то есть, bash, встретив эти символы, закончит всю логику внутри case перейдет к следующей инструкции после esac. Bash после этих символов завершает выполнение оператора case.

Но если нужно, чтобы bash проверял и другие варианты в case (или выполнял другие действия) можно использовать комбинации символов ;;& и ;& . Наглядно:

case $filename in
	./*) echo -n "local"         # Начинается с ./
		;&                           # Спуститься к СЛЕДУЮЩЕМУ варианту
	[^/]*) echo -n "relative"    # Начинается с любого символа, кроме /
		;;&                          # Проверить совпадения с ДРУГИМИ вариантами
	/*) echo -n "absolute"       # Начинается с /
		;&                           # Спуститься к СЛЕДУЮЩЕМУ варианту
	*/*) echo "pathname"         # В имени есть /
		;;                           # Завершить
	*) echo "filename"           # Вcё остальное
		;;                           # Завершить
esac

Шаблоны в примере будут сравниваться по порядку со значением $filename.

;& говорит спуститься дальше и выполнить все команды, перечисленные в следующем варианте без проверки совпадения с шаблоном этого варианта.

read num
case $num in
	1) echo 1 ;&
	2) echo 2 ;;
esac

То есть, в случае выше, если даже будет введен 1 выведется и 2.

А ;;& говорит проверить другие варианты по порядку.
Т.к. применение этих символов не особо понятно не знакомым с bash людям - лучше тщательно комментировать код.


Соус: Книга “Идиомы Bash Глава 3. На всякий случай: оператор Case

bash