Shell脚本中case语句的详细使用指南

case语句是Shell脚本中用于多条件分支选择的控制结构,类似于其他编程语言中的switch-case,但语法更具Shell特色。它特别适合处理基于单一变量的多种可能值的场景,比多层if-elif-else嵌套更清晰、高效。

图片[1]_Shell脚本中case语句的详细使用指南_知途无界

一、基本语法结构

标准格式

case 变量 in
    模式1)
        # 模式1匹配时执行的命令
        ;;
    模式2|模式3)  # 支持多模式合并(用|分隔)
        # 模式2或模式3匹配时执行的命令
        ;;
    *)
        # 默认情况(类似switch中的default)
        ;;
esac

关键符号说明

  • caseesac 是固定关键字(esaccase 的反向拼写,表示结束)。
  • 变量 是要匹配的目标(通常是用户输入、命令行参数等)。
  • 模式 是匹配规则(支持通配符和正则片段)。
  • ;; 表示当前分支的结束(类似其他语言中的break)。
  • | 用于合并多个模式(逻辑“或”关系)。

二、核心使用示例

示例1:基础匹配(菜单选择)

#!/bin/bash

echo "请选择操作:"
echo "1) 查看当前目录"
echo "2) 查看磁盘使用"
echo "3) 退出"

read -p "输入选项 (1-3): " choice

case $choice in
    1)
        ls -l
        ;;
    2)
        df -h
        ;;
    3)
        echo "退出脚本"
        ;;
    *)
        echo "无效选项,请重新输入!"
        ;;
esac

说明​:用户输入数字后,case 根据 $choice 的值执行对应分支,* 是默认分支(匹配所有未匹配的情况)。


示例2:多模式合并(简写分支)

#!/bin/bash

read -p "输入文件类型 (txt/log/doc): " filetype

case $filetype in
    txt|log)      # 匹配txt或log
        echo "这是文本类文件,使用cat查看"
        ;;
    doc|docx)     # 匹配doc或docx
        echo "这是Word文档,建议用libreoffice打开"
        ;;
    *)
        echo "未知文件类型"
        ;;
esac

说明​:通过 | 合并多个模式,减少重复分支(例如同时处理 .txt.log 文件)。


示例3:处理命令行参数($1)

#!/bin/bash

case $1 in
    start)
        echo "启动服务..."
        systemctl start nginx
        ;;
    stop)
        echo "停止服务..."
        systemctl stop nginx
        ;;
    restart)
        echo "重启服务..."
        systemctl restart nginx
        ;;
    status)
        echo "查看状态..."
        systemctl status nginx
        ;;
    *)
        echo "用法: $0 {start|stop|restart|status}"
        exit 1
        ;;
esac

典型场景​:脚本通过命令行参数(如 ./script.sh start)控制不同操作,$1 是第一个参数。


示例4:匹配路径或复杂模式

#!/bin/bash

read -p "输入路径: " path

case $path in
    /home/*)      # 匹配以/home/开头的路径
        echo "这是用户家目录下的路径"
        ;;
    /etc/*.conf)  # 匹配/etc/下以.conf结尾的文件(注意:实际需用引号或转义)
        echo "这是配置文件"
        ;;
    *)
        echo "其他路径"
        ;;
esac

注意​:若模式中包含特殊字符(如*?),建议用引号包裹变量(如 case "$path" in),避免意外解析。


三、进阶技巧与注意事项

1. 通配符支持

  • *:匹配任意字符(包括空字符)。
  • ?:匹配单个任意字符。
  • [abc]:匹配a、b或c中的任意一个字符。
  • [a-z]:匹配a到z范围内的任意一个字符。

示例​:匹配数字或字母开头的输入

case $input in
    [0-9]*)     # 以数字开头
        echo "输入以数字开头"
        ;;
    [a-zA-Z]*)  # 以字母开头
        echo "输入以字母开头"
        ;;
esac

2. 变量引用规范

  • 推荐始终用双引号包裹变量​(避免空值或空格导致的语法错误): case "$variable" in "value") # 命令 ;; esac
  • 若变量可能为空,不加引号可能导致模式匹配异常(如 case $unset_var in 可能直接报错)。

3. 默认分支(*)的重要性

  • 务必包含 *) 分支​:处理未预期的输入,避免脚本因未匹配而静默执行错误逻辑。
  • 示例中的 *) 通常用于提示用户输入错误或执行兜底操作。

4. 与if-elif-else的对比

场景推荐结构原因
单一变量的多值匹配case代码更简洁,可读性更高(尤其当分支超过3个时)
复杂条件(如范围比较)if-elif-elsecase 不支持直接比较数值范围(如 if [ $num -gt 10 ]
模式匹配(通配符)case天然支持 *? 等通配符,无需额外工具

何时用if替代​:当需要判断数值范围(如 if [ $age -gt 18 ])、文件是否存在(如 if [ -f file.txt ])等非单纯值匹配时。


四、完整实战案例

案例:用户输入处理脚本

#!/bin/bash

echo "=== 系统工具菜单 ==="
echo "1) 查看IP地址"
echo "2) 查看内存使用"
echo "3) 查看磁盘空间"
echo "4) 退出"

read -p "请选择功能 (1-4): " option

case $option in
    1)
        echo "当前IP: $(hostname -I | awk '{print $1}')"
        ;;
    2)
        free -h | grep -E "Mem|Swap"
        ;;
    3)
        df -h | grep -v "tmpfs"
        ;;
    4)
        echo "再见!"
        exit 0
        ;;
    *)
        echo "错误:请输入1-4之间的数字!" >&2  # 错误信息输出到stderr
        exit 1
        ;;
esac

功能说明​:根据用户输入调用不同系统命令,展示IP、内存或磁盘信息,体现了case在菜单类脚本中的典型应用。


总结

  • 何时用case​:当需要基于单一变量的多个可能值进行分支处理时(尤其是字符串匹配、菜单选择、命令行参数解析)。
  • 优势​:代码结构清晰、可读性强,避免了多层if-elif-else嵌套的复杂性。
  • 关键点​:注意变量引用规范(推荐加双引号)、包含默认分支(*)、利用多模式合并(|)简化逻辑。

掌握case语句后,可以更高效地编写交互式脚本、自动化工具和系统管理任务!

© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞17 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容