5.3.1 条件判断与多分支选择
条件判断与多分支选择#
条件判断用于根据运行时结果决定执行路径,是运维脚本中最常见的控制结构。本节以 Bash 为主,覆盖常用测试表达式、分支语法、组合条件与最佳实践,并提供可执行示例、排错与练习。
原理草图:条件判断执行流#
1. 环境检查与“安装”#
Bash 通常随 Linux 自带,无需单独安装,但建议确认版本:
bash --version
# 预期输出示例:
# GNU bash, version 4.4.20(1)-release
2. 基本条件判断(if)#
常用测试方式:[/test 与 [[ ]]。
示例:文件存在性与权限检查
#!/usr/bin/env bash
# 文件路径:/tmp/check_file.sh
FILE="/etc/ssh/sshd_config"
if [ -f "$FILE" ]; then
echo "存在: $FILE"
if [ -r "$FILE" ] && [ -s "$FILE" ]; then
echo "可读且非空"
else
echo "不可读或为空"
fi
else
echo "不存在: $FILE"
fi
执行:
chmod +x /tmp/check_file.sh
/tmp/check_file.sh
命令解释
- -f:判断是否为普通文件
- -r:判断是否可读
- -s:判断文件大小是否大于 0
- &&:逻辑与(同时成立)
3. 数值与字符串比较#
#!/usr/bin/env bash
# 文件路径:/tmp/compare.sh
CPU_LOAD=3
HOST="node-01"
if [ "$CPU_LOAD" -ge 4 ]; then
echo "负载高: $CPU_LOAD"
elif [ "$CPU_LOAD" -ge 2 ]; then
echo "负载中: $CPU_LOAD"
else
echo "负载低: $CPU_LOAD"
fi
if [[ "$HOST" == node-* ]]; then
echo "主机名匹配:$HOST"
fi
命令解释
- -ge:大于等于(数字比较)
- ==:字符串相等([[ ]] 中可用通配符)
4. 多分支选择(case)#
适用于多选一的清晰分支。
#!/usr/bin/env bash
# 文件路径:/tmp/service_ctl.sh
ACTION="$1"
case "$ACTION" in
start)
echo "启动服务..."
;;
stop)
echo "停止服务..."
;;
restart|reload)
echo "重启/重载服务..."
;;
*)
echo "用法: $0 {start|stop|restart|reload}"
exit 1
;;
esac
执行:
chmod +x /tmp/service_ctl.sh
/tmp/service_ctl.sh restart
5. 组合条件与命令返回值判断#
命令执行成功返回码为 0,失败为非 0。
#!/usr/bin/env bash
# 文件路径:/tmp/ping_check.sh
IP="8.8.8.8"
if ping -c 1 -W 1 "$IP" >/dev/null 2>&1; then
echo "网络通畅: $IP"
else
echo "网络不可达: $IP"
fi
命令解释
- ping -c 1 -W 1:发送 1 个包,超时 1 秒
- >/dev/null 2>&1:丢弃标准输出与错误输出
6. 典型排错与注意事项#
- 错误:
[: missing ]
原因:[与]必须有空格
bash # 错误 if [ -f /etc/passwd]; then echo ok; fi # 正确 if [ -f /etc/passwd ]; then echo ok; fi - 错误:
unary operator expected
原因:变量为空且未加引号
bash # 错误 if [ $VAR = "x" ]; then echo ok; fi # 正确 if [ "$VAR" = "x" ]; then echo ok; fi
7. 练习题(含目标)#
- 根据磁盘使用率输出告警级别
- 输入:df -P /的使用率
- 目标:>=90 输出“严重”,>=80 输出“警告”,否则“正常” - 按参数控制 Nginx 行为
- 输入:start|stop|reload|status
- 目标:使用case输出对应动作提示 - 检查端口是否监听
- 目标:使用ss -lnt判断 80 端口是否监听,输出 “up/down”
示例参考(练习1):
#!/usr/bin/env bash
# 文件路径:/tmp/disk_alert.sh
USE=$(df -P / | awk 'NR==2{gsub("%","",$5); print $5}')
if [ "$USE" -ge 90 ]; then
echo "严重: ${USE}%"
elif [ "$USE" -ge 80 ]; then
echo "警告: ${USE}%"
else
echo "正常: ${USE}%"
fi