#!/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
那么为什么“ *)
”选项也有效呢?
答案1
发生这种情况的原因是“生产”子句以 结尾;;&
。
以下是bash 手册对此有如下评论:
[...] 使用 '
;;&
' 代替 ';;
' 会导致 shell 测试下一个子句中的模式(如果有),并执行任何相关的 命令列表如果匹配成功,则继续执行 case 语句,就好像模式列表未匹配一样。
因此它匹配production)
,执行该子句(设置ENVIRONMENT_NS
为“prod”),然后查找其他匹配子句。默认子句*)
也匹配(因为它匹配所有内容),因此它还执行该子句(打印“未找到匹配的信息”)。
如果您不希望它除了执行任何匹配的前置子句之外还执行默认子句,请不要使用;;&
。
答案2
该命令的语法
case
是:case word in [ [(] pattern [| pattern]…) command-list ;;]… esac
[…]
可能有任意数量的 case 子句,每个子句都以
;;
、;&
或结尾;;&
。第一个匹配的模式决定command-list
执行的。[…]如果
;;
使用运算符,则在第一个模式匹配之后不会尝试后续匹配。[…] 使用;;&
in place of;;
会导致 shell 测试下一个子句中的模式(如果有),并command-list
在成功匹配时执行任何相关模式,继续执行 case 语句,就好像模式列表未匹配一样。
(来源)
您使用了;;&
,而不是;;
在模式为 的测试子句中production
。 有匹配项,因此ENVIRONMENT_NS=prod
执行了;但由于;;&
Bash 继续“继续执行 case 语句,就好像模式列表未匹配一样”。 下一个匹配的模式是*
。
我认为;;&
所讨论的代码中的每一个都应该是;;
。
附注:
- POSIX 规范
case
仅提到;;
。;;&
是不可移植的。 - 不引用是安全的
case $ENVIRONMENT in
, 但是$ENVIRONMENT_NS
之后echo
原则上应双引号。