必须写*)分支作为case语句的兜底,位置在最后,用于处理值存在但不合法的情况;应输出具体错误、用法提示并exit非零码;空值需前置校验;复杂逻辑应封装为函数。

用 *) 分支作为兜底是 case 语句的标准做法,关键在于写得清晰、安全、有信息量,而不是简单 echo 一句“未知”就结束。
必须写 *) 分支,且放在最后
case 语句不会自动跳到默认分支,不写 *) 就意味着没匹配时什么也不做——脚本静默失败,这是运维事故的常见源头。
- 它不是可选项,而是健壮性底线
- 位置必须在所有具体模式之后,否则会提前截断匹配
- 哪怕只是 exit 1,也比留空强
兜底内容要带上下文和动作建议
用户输错参数或变量为空时,只显示“未知输入”无助于排查。应明确指出问题在哪、该怎么改。
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 打印出实际值:例如
echo "错误:不支持的操作 '$1',请使用 start|stop|restart|status" - 附带简明用法:比如
echo "用法:$0 {start|stop|status}" - 必要时退出并返回非零状态码:
exit 2,方便上游调用者判断失败
对空值和空白字符做前置防护
很多“未匹配”其实源于变量本身为空或只有空格,*) 虽能兜住,但体验差。更优雅的方式是在 case 外先清理。
- 用
[[ -z "${1//[$' \t\n']}" ]]判断参数是否实质为空(剔除所有空白符) - 提前提示并退出:
echo "错误:缺少操作指令"; exit 1 - 这样
*)就真正留给“值存在但不合法”的情况,职责更清晰
复杂场景可用子 case 或函数封装兜底逻辑
当主 case 分支多、兜底行为也需要分情况(如日志记录 + 发告警 + 退出),直接堆命令会让主结构臃肿。
- 把兜底动作抽成函数:
handle_unknown() { log_error "unhandled: $1"; send_alert; exit 3; } - 在
*)中只调用:handle_unknown "$1";; - 后续扩展告警渠道或日志级别,只需改函数,不影响主流程

















