【网络运维】Shell 脚本编程:case 条件语句
Shell 脚本编程:case 条件语句
case 语句概述
case 条件语句是一种多分支的条件判断结构,相当于多分支的 if/elif/else 语句,但语法更规范、可读性更强,常用于实现系统服务启动脚本等企业级应用场景。
在 case 语句中,程序会将变量的值与多个模式进行匹配:
- 若匹配成功,则执行对应指令块,直到遇到
;;
跳出; - 若所有模式都不匹配,则执行
*)
对应的默认指令块; - 支持使用管道符
|
实现多模式匹配。
case 语句语法结构
基础语法格式
case "变量值" in模式1)指令1...;;模式2)指令2...;;*)默认指令...;;
esac
基础应用示例
示例1:判断用户输入数字
#!/bin/bash
read -p "请输入一个1-3之间的数字:" num
case $num in1)echo "您输入的数字是:$num";;2)echo "您输入的数字是:$num";;3)echo "您输入的数字是:$num";;*)echo "请输入一个1-3之间的数字。";;
esac
注释说明:
read -p
用于提示用户输入;$num
是用户输入的变量;*)
处理所有未匹配的情况,相当于 else。
示例2:输出带颜色的字符串
#!/bin/bash
case $1 inPASS)echo -e '\033[1;32mPASS\033[0;39m' # 绿色加粗;;FAIL)echo -e '\033[1;31mFAIL\033[0;39m' # 红色加粗;;DONE)echo -e '\033[1;35mDONE\033[0;39m' # 紫色加粗;;*)echo "Usage: $0 PASS|FAIL|DONE" # 使用提示;;
esac
注释说明:
\033[1;32m
表示开始绿色加粗;\033[0;39m
表示重置颜色;$1
是脚本的第一个参数。
case应用案例
案例1:控制 sshd 服务
基础版
#!/bin/bash
case $1 in start)systemctl start sshd;;stop)systemctl stop sshd;;restart | reload ) systemctl restart sshd;; status ) systemctl status sshd;; *)echo "Usage: $0 start|stop|restart|reload|status";;
esac
简化版(推荐)
#!/bin/bash
case $1 in start | stop | restart | reload | status)systemctl $1 sshd # 使用 $1 直接传递动作;;*)echo "Usage: $0 start|stop|restart|reload|status";;
esac
案例2:用户管理系统
功能要求:
- 支持添加、删除、查找用户;
- 用户信息保存在
/etc/users
中; - 文件需防误删改(使用
chattr +i
); - 提供使用提示和错误处理。
实现代码(函数化版本)
#!/bin/bash# 必须root权限执行
[ $UID -ne 0 ] && echo 'Please run as root' && exit 1# 用户信息文件
users_info_file=/etc/users
[ -f ${users_info_file} ] || touch ${users_info_file}# 使用说明函数
function usage () {echo "Usage: user-mgr [ [-add|-a ] | [ -d|-del ] | [ -s|-search ] ] username" exit 2
}# 查找用户函数
function search_user () {if grep -q "username: $1" ${users_info_file}; thenecho "$1 is exist."return 0elseecho "$1 is not exist."return 1fi
}# 添加用户函数
function add_user () {search_user $1 &>/dev/nullif [ $? -eq 0 ]; thenecho "$1 is already exist."elsechattr -i ${users_info_file} # 解除文件保护echo "username: $1" >> ${users_info_file} && echo "Add User Success."chattr +i ${users_info_file} # 重新加保护fi
}# 删除用户函数
function del_user () {search_user $1 &>/dev/nullif [ $? -eq 1 ]; thenecho "$1 is not exist."elsechattr -i ${users_info_file}sed -i "/username: $1/d" ${users_info_file} && echo "Del User Success."chattr +i ${users_info_file}fi
}# 参数检查
[ $# -ne 2 ] && usage# 主逻辑
case $1 in-a|-add)shift # 移除第一个参数,剩下用户名add_user $1;;-d|-del)shiftdel_user $1;;-s|-search)shiftsearch_user $1;;*)usage;;
esac
注释说明:
chattr ±i
用于设置/取消文件不可修改属性;shift
用于移动参数位置;grep -q
静默模式,仅用于判断是否存在。
系统脚本范例参考
在 Linux 系统中,很多服务的启动脚本都使用 case 语句实现,例如:
/etc/init.d/network
/etc/init.d/nginx
/etc/init.d/mysql
这些脚本通常由 network-scripts
、nginx
、mysql-server
等软件包提供。
case 语句与 if 语句对照表
特性对比 | case 语句 | if 语句 |
---|---|---|
适用场景 | 固定值匹配 | 范围判断、复杂逻辑 |
可读性 | 高 | 中 |
灵活性 | 中 | 高 |
企业应用 | 服务脚本 | 通用逻辑 |
总结:
- case 语句适用场景:变量值为固定、有限的字符串或数字,如服务管理命令(start/stop/status);
- if 语句适用场景:复杂的条件判断、范围判断、数值比较等;
- 可读性对比:case 语句结构清晰,更适合管理多分支固定值场景;
- 扩展性:case 支持管道符匹配多个模式,如
start|begin
; - 企业实践:推荐在服务管理脚本中使用 case,通用逻辑中使用 if。
case 语句是 Shell 脚本中处理多分支选择的利器,合理使用可大幅提升脚本的可读性和维护性。