#!/bin/bash
ENVIRONMENT="production"
case $ENVIRONMENT in
production)
ENVIRONMENT_NS=prod
;;&
staging)
ENVIRONMENT_NS=staging
;;&
development)
ENVIRONMENT_NS=pga
;;
*)
echo "No matching information found"
esac
echo $ENVIRONMENT_NS
./test.sh
No matching information found
prod
так почему «*)«вариант тоже работал?»
2 ответа
Это происходит из-за того, что конец предложения «производство» завершается ;;&.
Вот что руководство по bash говорит об этом:
[…] С помощью ‘
;;&‘ на месте ‘;;‘заставляет оболочку проверять шаблоны в следующем предложении, если таковые имеются, и выполнять любые связанные
список команд при успешном совпадении продолжение выполнения оператора case, как если бы список шаблонов не совпадал.
Так что это соответствует production), выполняет это предложение (установка ENVIRONMENT_NS to «prod»), затем ищет дополнительные соответствующие предложения. Предложение по умолчанию, *), также совпадает (потому что он соответствует всему), поэтому он также выполняет это предложение (выводит «Соответствующая информация не найдена»).
Если вы не хотите, чтобы он выполнял предложение по умолчанию в дополнение к любым соответствующим предыдущим предложениям, не используйте ;;&.
Синтаксис
caseкоманда:case word in [ [(] pattern [| pattern]…) command-list ;;]… esac[…]
Может быть произвольное количество предложений case, каждое из которых завершается
;;,;&, или же;;&. Первый совпадающий шаблон определяетcommand-listчто выполнено. […]Если
;;используется оператор, после первого сопоставления с шаблоном попытки последующих сопоставлений не предпринимаются. […] С помощью;;&на месте;;заставляет оболочку проверять шаблоны в следующем предложении, если таковые имеются, и выполнять любые связанныеcommand-listпри успешном совпадении продолжение выполнения оператора case, как если бы список шаблонов не совпадал.
(источник)
Ты использовал ;;&, нет ;; в предложении теста, где шаблон production. Был матч, так что ENVIRONMENT_NS=prod был казнен; но из-за ;;& Баш продолжал «продолжать выполнение оператора case, как если бы список шаблонов не совпал». Следующим подходящим шаблоном был *.
Я думаю каждый ;;& в рассматриваемом коде должно быть ;;.
Боковые примечания:
- Спецификация POSIX
caseтолько упоминания;;.;;&не переносится. - Безопасно не цитировать в
case $ENVIRONMENT in, но$ENVIRONMENT_NSпослеechoследует заключать в двойные кавычки по принципу.
