人人都会AI编程

14.1 条件判断

更新时间:2026-07-12

if/else/elif 分支结构

if 语句根据命令的退出状态码(0 为真,非 0 为假)来决定执行哪个分支。它通常与 test 命令或 [ ][[ ]] 条件表达式搭配使用。

基本语法

if 条件命令; then
    命令块
elif 另一个条件; then
    命令块
else
    命令块
fi

elifelse 都是可选的,fi 是结束标记。

常用条件测试

  • 字符串比较[ "$a" = "$b" ][ -z "$str" ](是否为空)、[ -n "$str" ](是否非空)
  • 数值比较[ "$x" -gt 10 ](大于)、-lt(小于)、-eq(等于)、-ne(不等于)
  • 文件测试[ -f "$file" ](是否存在且为普通文件)、[ -d "$dir" ](是否为目录)、[ -x "$script" ](是否可执行)
  • 逻辑组合[ 条件1 -a 条件2 ](与)、[ 条件1 -o 条件2 ](或),或者使用 [[ ]]&&||(推荐)

实用示例

#!/bin/bash
backup_dir="/var/backups"

if [ ! -d "$backup_dir" ]; then
    echo "备份目录不存在,正在创建..."
    mkdir -p "$backup_dir"
elif [ -z "$(ls -A "$backup_dir")" ]; then
    echo "备份目录已存在,但为空。"
else
    echo "备份目录已存在,包含 $(ls -1 "$backup_dir" | wc -l) 个文件。"
fi

注意点

  • 变量要用双引号引起来,防止值为空或包含空格时语法错误。
  • [ ]test 命令的别名,要求操作符两边都有空格(例如 [ "$a" = "$b" ] 而非 ["$a"="$b"])。
  • 在 bash 中,优先使用 [[ ]]:它支持正则匹配 =~、模式匹配 == pattern,且无需对变量加引号防止分词,更安全方便。

case 多分支结构

当需要将一个变量的值与多个模式进行匹配时,case 比一连串 if/elif 更清晰高效。它常用于处理脚本的启动参数、菜单选择或根据文件名扩展名执行不同操作。

基本语法

case 变量 in
    模式1)
        命令块 ;;
    模式2)
        命令块 ;;
    *)
        命令块 ;;   # 默认分支
esac
  • 每个分支末尾用 ;; 结束。
  • * 匹配所有未命中情况,类似 default
  • 模式可以使用通配符:*(任意字符串)、?(任意单个字符)、[abc](字符集)、|(或,如 yes|y

实用示例:服务控制脚本

#!/bin/bash
case "$1" in
    start)
        echo "正在启动 Web 服务..."
        systemctl start nginx
        ;;
    stop)
        echo "正在停止 Web 服务..."
        systemctl stop nginx
        ;;
    restart|reload)
        echo "正在重启 Web 服务..."
        systemctl restart nginx
        ;;
    status)
        systemctl status nginx
        ;;
    *)
        echo "用法: $0 {start|stop|restart|status}"
        exit 1
esac

另一个经典例子:根据文件后缀分类处理

for file in *; do
    case "$file" in
        *.sh)   echo "$file 是 Shell 脚本" ;;
        *.txt)  echo "$file 是文本文件" ;;
        *.png|*.jpg|*.gif)
                echo "$file 是图片文件" ;;
        *)      echo "$file 类型未知" ;;
    esac
done

注意点

  • case 内的模式是 shell 的通配符,不是正则表达式,但支持 | 表示或。
  • 很长的 if/elif 链(超过三四种情况)多半可以用 case 重构。
  • 可以在分支内使用任何命令,包括设置变量、调用函数;需要跳出 case 时只需到达 ;;

两者选择建议

  • if:适用于需要根据命令执行成功与否、复杂逻辑表达式(如组合多个文件测试和数值比较)做决策的场景。
  • case:适用于一个变量有多个固定值或通配模式,且每个分支动作差异明显的场景,代码更紧凑易读。

实际脚本中,它们经常配合使用,例如先用 if 检查环境,再用 case 处理用户输入。掌握这两种结构是编写健壮、可读 Shell 脚本的关键一步。