case语句是Shell脚本中用于多条件分支选择的控制结构,类似于其他编程语言中的switch-case,但语法更具Shell特色。它特别适合处理基于单一变量的多种可能值的场景,比多层if-elif-else嵌套更清晰、高效。
![图片[1]_Shell脚本中case语句的详细使用指南_知途无界](https://zhituwujie.com/wp-content/uploads/2025/09/d2b5ca33bd20250922090405-1024x685.png)
一、基本语法结构
标准格式
case 变量 in
模式1)
# 模式1匹配时执行的命令
;;
模式2|模式3) # 支持多模式合并(用|分隔)
# 模式2或模式3匹配时执行的命令
;;
*)
# 默认情况(类似switch中的default)
;;
esac
关键符号说明
case和esac是固定关键字(esac是case的反向拼写,表示结束)。变量是要匹配的目标(通常是用户输入、命令行参数等)。模式是匹配规则(支持通配符和正则片段)。;;表示当前分支的结束(类似其他语言中的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-else | case 不支持直接比较数值范围(如 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

























暂无评论内容