#!/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
следует заключать в двойные кавычки по принципу.