case 语句

当判断条件有很多种可能时,用 if-elif 会写得很长。case 语句更适合这种多分支场景,代码更清晰。

基本语法

case 变量 in
    模式1)
        命令
        ;;
    模式2)
        命令
        ;;
    *)
        默认命令
        ;;
esac

注意:

  • 每个模式以 ) 结束
  • 每个分支以 ;; 结束
  • * 是默认分支,类似 default
  • esac 是 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,条件判断用 if。

注意事项

变量最好加引号

case "$VAR" in
    # ...
esac

空值处理

case "${VAR:-default}" in
    # ...
esac

不要忘记 ;;

每个分支必须以 ;; 结束,否则会继续执行下一个分支。

小结

case 语句要点:

  1. 适合多分支等值匹配
  2. 支持通配符和字符范围
  3. | 可以匹配多个模式
  4. * 是默认分支
  5. 别忘了 ;;esac