case语句 #

一、case语句基础 #

1.1 基本语法 #

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

1.2 简单示例 #

bash
#!/bin/bash

day="Monday"

case $day in
    Monday)
        echo "星期一"
        ;;
    Tuesday)
        echo "星期二"
        ;;
    Wednesday)
        echo "星期三"
        ;;
    Thursday)
        echo "星期四"
        ;;
    Friday)
        echo "星期五"
        ;;
    Saturday|Sunday)
        echo "周末"
        ;;
    *)
        echo "未知日期"
        ;;
esac

二、模式匹配 #

2.1 基本模式 #

bash
#!/bin/bash

read -p "请输入选项 (y/n): " choice

case $choice in
    y|Y|yes|YES)
        echo "你选择了是"
        ;;
    n|N|no|NO)
        echo "你选择了否"
        ;;
    *)
        echo "无效选项"
        ;;
esac

2.2 通配符模式 #

bash
#!/bin/bash

file="document.txt"

case $file in
    *.txt)
        echo "文本文件"
        ;;
    *.sh)
        echo "Shell脚本"
        ;;
    *.jpg|*.png|*.gif)
        echo "图片文件"
        ;;
    *)
        echo "其他文件"
        ;;
esac

2.3 字符范围 #

bash
#!/bin/bash

char="a"

case $char in
    [a-z])
        echo "小写字母"
        ;;
    [A-Z])
        echo "大写字母"
        ;;
    [0-9])
        echo "数字"
        ;;
    *)
        echo "其他字符"
        ;;
esac

2.4 组合模式 #

bash
#!/bin/bash

input="Hello123"

case $input in
    [a-z]*)
        echo "以小写字母开头"
        ;;
    [A-Z]*)
        echo "以大写字母开头"
        ;;
    [0-9]*)
        echo "以数字开头"
        ;;
    *[^a-zA-Z0-9]*)
        echo "包含特殊字符"
        ;;
    *)
        echo "其他情况"
        ;;
esac

三、case语句高级用法 #

3.1 命令参数处理 #

bash
#!/bin/bash

while [[ $# -gt 0 ]]; do
    case "$1" in
        -h|--help)
            echo "用法: $0 [选项]"
            echo "  -h, --help     显示帮助"
            echo "  -v, --version  显示版本"
            echo "  -f, --file     指定文件"
            exit 0
            ;;
        -v|--version)
            echo "版本: 1.0.0"
            exit 0
            ;;
        -f|--file)
            file="$2"
            shift 2
            ;;
        -*)
            echo "错误: 未知选项 $1"
            exit 1
            ;;
        *)
            echo "错误: 未知参数 $1"
            exit 1
            ;;
    esac
done

echo "文件: ${file:-未指定}"

3.2 服务管理脚本 #

bash
#!/bin/bash

action="$1"
service="nginx"

case "$action" in
    start)
        echo "启动 $service..."
        systemctl start "$service"
        ;;
    stop)
        echo "停止 $service..."
        systemctl stop "$service"
        ;;
    restart)
        echo "重启 $service..."
        systemctl restart "$service"
        ;;
    status)
        systemctl status "$service"
        ;;
    reload)
        echo "重载 $service 配置..."
        systemctl reload "$service"
        ;;
    enable)
        echo "启用 $service 开机自启..."
        systemctl enable "$service"
        ;;
    disable)
        echo "禁用 $service 开机自启..."
        systemctl disable "$service"
        ;;
    *)
        echo "用法: $0 {start|stop|restart|status|reload|enable|disable}"
        exit 1
        ;;
esac

3.3 菜单系统 #

bash
#!/bin/bash

show_menu() {
    clear
    echo "========================"
    echo "    系统管理菜单"
    echo "========================"
    echo "1. 查看系统信息"
    echo "2. 查看磁盘使用"
    echo "3. 查看内存使用"
    echo "4. 查看进程列表"
    echo "5. 退出"
    echo "========================"
}

while true; do
    show_menu
    read -p "请选择 [1-5]: " choice
    
    case $choice in
        1)
            echo ""
            echo "=== 系统信息 ==="
            uname -a
            echo ""
            read -p "按回车继续..."
            ;;
        2)
            echo ""
            echo "=== 磁盘使用 ==="
            df -h
            echo ""
            read -p "按回车继续..."
            ;;
        3)
            echo ""
            echo "=== 内存使用 ==="
            free -h
            echo ""
            read -p "按回车继续..."
            ;;
        4)
            echo ""
            echo "=== 进程列表 ==="
            ps aux | head -20
            echo ""
            read -p "按回车继续..."
            ;;
        5)
            echo "再见!"
            exit 0
            ;;
        *)
            echo "无效选择,请重新输入"
            sleep 1
            ;;
    esac
done

3.4 操作系统检测 #

bash
#!/bin/bash

detect_os() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS=$ID
    elif [ -f /etc/redhat-release ]; then
        OS="rhel"
    elif [ -f /etc/debian_version ]; then
        OS="debian"
    else
        OS=$(uname -s)
    fi
    
    case "$OS" in
        ubuntu|debian)
            echo "Debian系列系统"
            PKG_MANAGER="apt"
            ;;
        centos|rhel|fedora)
            echo "RedHat系列系统"
            PKG_MANAGER="yum"
            ;;
        arch|manjaro)
            echo "Arch系列系统"
            PKG_MANAGER="pacman"
            ;;
        alpine)
            echo "Alpine Linux"
            PKG_MANAGER="apk"
            ;;
        Darwin)
            echo "macOS"
            PKG_MANAGER="brew"
            ;;
        *)
            echo "未知系统: $OS"
            PKG_MANAGER="unknown"
            ;;
    esac
}

detect_os
echo "包管理器: $PKG_MANAGER"

四、case语句与正则表达式 #

4.1 简单正则匹配 #

bash
#!/bin/bash

validate_input() {
    local input="$1"
    
    case "$input" in
        [0-9]*)
            echo "以数字开头"
            ;;
        [a-zA-Z]*)
            echo "以字母开头"
            ;;
        *)
            echo "以其他字符开头"
            ;;
    esac
}

validate_input "123"
validate_input "abc"
validate_input "@#$"

4.2 复杂模式匹配 #

bash
#!/bin/bash

classify_file() {
    local file="$1"
    local filename=$(basename "$file")
    
    case "$filename" in
        Makefile|makefile)
            echo "Make构建文件"
            ;;
        README*|readme*)
            echo "说明文档"
            ;;
        LICENSE|license*)
            echo "许可证文件"
            ;;
        *.tar.gz|*.tgz)
            echo "Gzip压缩包"
            ;;
        *.tar.bz2|*.tbz2)
            echo "Bzip2压缩包"
            ;;
        *.zip)
            echo "ZIP压缩包"
            ;;
        *.tar.xz|*.txz)
            echo "XZ压缩包"
            ;;
        *)
            echo "其他文件"
            ;;
    esac
}

classify_file "README.md"
classify_file "project.tar.gz"
classify_file "Makefile"

五、case语句嵌套 #

5.1 嵌套case示例 #

bash
#!/bin/bash

os="linux"
distro="ubuntu"

case "$os" in
    linux)
        echo "Linux系统"
        case "$distro" in
            ubuntu|debian)
                echo "  Debian系列"
                ;;
            centos|rhel|fedora)
                echo "  RedHat系列"
                ;;
            arch|manjaro)
                echo "  Arch系列"
                ;;
            *)
                echo "  其他发行版"
                ;;
        esac
        ;;
    darwin)
        echo "macOS系统"
        ;;
    windows)
        echo "Windows系统"
        ;;
    *)
        echo "未知系统"
        ;;
esac

5.2 使用函数替代嵌套 #

bash
#!/bin/bash

handle_linux() {
    local distro="$1"
    case "$distro" in
        ubuntu|debian)
            echo "Debian系列"
            ;;
        centos|rhel|fedora)
            echo "RedHat系列"
            ;;
        *)
            echo "其他发行版"
            ;;
    esac
}

os="linux"
distro="ubuntu"

case "$os" in
    linux)
        echo "Linux系统"
        handle_linux "$distro"
        ;;
    darwin)
        echo "macOS系统"
        ;;
    *)
        echo "未知系统"
        ;;
esac

六、实战示例 #

6.1 日志级别处理 #

bash
#!/bin/bash

log() {
    local level="$1"
    local message="$2"
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    
    case "$level" in
        DEBUG)
            echo "[$timestamp] [DEBUG] $message"
            ;;
        INFO)
            echo "[$timestamp] [INFO] $message"
            ;;
        WARN)
            echo "[$timestamp] [WARN] $message" >&2
            ;;
        ERROR)
            echo "[$timestamp] [ERROR] $message" >&2
            ;;
        FATAL)
            echo "[$timestamp] [FATAL] $message" >&2
            exit 1
            ;;
        *)
            echo "[$timestamp] [UNKNOWN] $message"
            ;;
    esac
}

log "INFO" "程序启动"
log "DEBUG" "调试信息"
log "ERROR" "发生错误"

6.2 文件类型处理 #

bash
#!/bin/bash

process_file() {
    local file="$1"
    
    if [[ ! -e "$file" ]]; then
        echo "文件不存在: $file"
        return 1
    fi
    
    case "$file" in
        *.tar.gz|*.tgz)
            echo "解压 tar.gz 文件..."
            tar -xzf "$file"
            ;;
        *.tar.bz2|*.tbz2)
            echo "解压 tar.bz2 文件..."
            tar -xjf "$file"
            ;;
        *.zip)
            echo "解压 zip 文件..."
            unzip "$file"
            ;;
        *.gz)
            echo "解压 gz 文件..."
            gunzip "$file"
            ;;
        *)
            echo "不支持的文件类型"
            return 1
            ;;
    esac
}

process_file "backup.tar.gz"

6.3 用户交互脚本 #

bash
#!/bin/bash

confirm() {
    local prompt="$1"
    local default="${2:-n}"
    
    if [[ "$default" == "y" ]]; then
        prompt="$prompt [Y/n]: "
    else
        prompt="$prompt [y/N]: "
    fi
    
    read -p "$prompt" answer
    answer=${answer:-$default}
    
    case "$answer" in
        y|Y|yes|YES|Yes)
            return 0
            ;;
        n|N|no|NO|No)
            return 1
            ;;
        *)
            echo "无效输入,使用默认值"
            [[ "$default" == "y" ]] && return 0 || return 1
            ;;
    esac
}

if confirm "是否继续?" "n"; then
    echo "用户选择继续"
else
    echo "用户选择取消"
fi

七、case语句最佳实践 #

7.1 代码风格 #

bash
#!/bin/bash

# 推荐:每个模式单独一行
case $var in
    pattern1)
        command
        ;;
    pattern2)
        command
        ;;
esac

# 推荐:使用缩进
case $var in
    pattern1)
        command1
        command2
        ;;
    pattern2)
        command
        ;;
esac

# 推荐:使用 | 组合多个模式
case $var in
    y|Y|yes|YES)
        echo "是"
        ;;
esac

7.2 注意事项 #

bash
#!/bin/bash

# 注意:;; 会终止case,;& 会继续执行下一个模式
case $var in
    pattern1)
        echo "匹配模式1"
        ;;&    # 继续匹配下一个模式
    pattern2)
        echo "匹配模式2"
        ;;     # 终止case
esac

# 注意:默认模式 * 放在最后
case $var in
    pattern1)
        command
        ;;
    *)          # 默认模式
        echo "未知选项"
        ;;
esac

八、总结 #

8.1 case语句要点 #

要点 说明
基本结构 case … in … esac
模式分隔 使用 | 分隔多个模式
命令结束 使用 ;; 结束每个模式块
默认模式 使用 * 匹配所有其他情况
通配符 支持 * ? [] 等通配符

8.2 下一步 #

你已经掌握了case语句,接下来让我们学习 for循环,了解循环结构!

最后更新:2026-03-27