当判断条件有很多种可能时,用 if-elif 会写得很长。case 语句更适合这种多分支场景,代码更清晰。
case 变量 in
模式1)
命令
;;
模式2)
命令
;;
*)
默认命令
;;
esac
注意:
) 结束;; 结束* 是默认分支,类似 defaultesac 是 case 倒过来写,表示结束#!/bin/bash
read -p "请输入选项 (start/stop/restart/status): " ACTION
case $ACTION in
start)
echo "启动服务..."
;;
stop)
echo "停止服务..."
;;
restart)
echo "重启服务..."
;;
status)
echo "查看状态..."
;;
*)
echo "未知选项: $ACTION"
echo "用法: $0 {start|stop|restart|status}"
;;
esac
case 支持多种模式匹配:
多值匹配
case $ANSWER in
y|Y|yes|YES)
echo "确认"
;;
n|N|no|NO)
echo "取消"
;;
esac
通配符匹配
FILE="document.txt"
case $FILE in
*.txt)
echo "文本文件"
;;
*.sh)
echo "脚本文件"
;;
*.jpg|*.png|*.gif)
echo "图片文件"
;;
*)
echo "其他文件"
;;
esac
字符范围
CHAR="a"
case $CHAR in
[a-z])
echo "小写字母"
;;
[A-Z])
echo "大写字母"
;;
[0-9])
echo "数字"
;;
*)
echo "其他字符"
;;
esac
组合模式
INPUT="Yes"
case $INPUT in
[yY]|[yY][eE][sS])
echo "确认"
;;
[nN]|[nN][oO])
echo "取消"
;;
*)
echo "无效输入"
;;
esac
服务管理脚本
#!/bin/bash
SERVICE_NAME="nginx"
case "$1" in
start)
systemctl start $SERVICE_NAME
echo "$SERVICE_NAME 已启动"
;;
stop)
systemctl stop $SERVICE_NAME
echo "$SERVICE_NAME 已停止"
;;
restart)
systemctl restart $SERVICE_NAME
echo "$SERVICE_NAME 已重启"
;;
status)
systemctl status $SERVICE_NAME
;;
*)
echo "用法: $0 {start|stop|restart|status}"
exit 1
;;
esac
菜单选择
#!/bin/bash
echo "=== 系统管理菜单 ==="
echo "1. 查看内存"
echo "2. 查看磁盘"
echo "3. 查看进程"
echo "4. 退出"
read -p "请选择 [1-4]: " CHOICE
case $CHOICE in
1)
free -h
;;
2)
df -h
;;
3)
ps aux | head -10
;;
4)
echo "再见"
exit 0
;;
*)
echo "无效选择"
exit 1
;;
esac
判断操作系统
#!/bin/bash
OS=$(uname -s)
case $OS in
Linux)
echo "Linux 系统"
;;
Darwin)
echo "macOS 系统"
;;
CYGWIN*|MINGW*)
echo "Windows 系统"
;;
*)
echo "未知系统: $OS"
;;
esac
处理信号
#!/bin/bash
trap 'handle_signal' SIGINT SIGTERM
handle_signal() {
echo "收到信号,正在退出..."
exit 0
}
# 模拟信号处理
case $1 in
--signal)
kill -SIGINT $$
;;
esac
什么时候用 case,什么时候用 if?
用 case 的场景:
用 if 的场景:
简单说:等值匹配用 case,条件判断用 if。
变量最好加引号
case "$VAR" in
# ...
esac
空值处理
case "${VAR:-default}" in
# ...
esac
不要忘记 ;;
每个分支必须以 ;; 结束,否则会继续执行下一个分支。
case 语句要点:
| 可以匹配多个模式* 是默认分支;; 和 esac