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. 练习题(含目标)#

  1. 根据磁盘使用率输出告警级别
    - 输入:df -P / 的使用率
    - 目标:>=90 输出“严重”,>=80 输出“警告”,否则“正常”
  2. 按参数控制 Nginx 行为
    - 输入:start|stop|reload|status
    - 目标:使用 case 输出对应动作提示
  3. 检查端口是否监听
    - 目标:使用 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