Shell IF 分支语句

《Shell IF 分支语句》深度学习版 🧠

🎉 欢迎来到 Shell 编程中极为关键的一章 —— if 分支语句。它是 Linux Shell 脚本中最常用的流程控制结构,是实现“判断逻辑”的核心工具。掌握它,你就能写出真正智能、自动化的脚本!


🎯 学习目标

  • 理解 if 语句的基本语法与执行流程
  • 掌握单分支、双分支、多分支的写法
  • 能在实际脚本中灵活使用 [ ][[ ]]
  • 学会结合 test 命令进行文件、字符串、数值等条件判断
  • 避免常见陷阱和语法错误,写出健壮可靠的 Shell 条件语句

⭐ 核心重点(知识点速览)

类型 内容 描述
单分支 if [ condition ]; then ... fi 如果条件成立则执行某段代码
双分支 if [ condition ]; then ... else ... fi 成立执行 A,否则执行 B
多分支 if [ condition1 ]; then ... elif [ condition2 ]; then ... else ... fi 多个条件依次判断
判断表达式 [ ], [[ ]] 使用 test 命令或其简写形式进行条件判断
文件测试 -f, -d, -r, -w, -x, -e 是否存在、是否为目录、是否有权限等
字符串比较 =, !=, -z, -n 是否相等、为空、非空
整数比较 -eq, -ne, -gt, -lt, -ge, -le 数值比较
逻辑运算 &&, `
返回值 $? 上一个命令的退出状态码,0 表示成功/真,非 0 表示失败/假

📖 详细讲解


一、基本语法结构

✅ 单分支结构

if [ condition ]; then
    # 条件成立时执行的代码
fi

✅ 双分支结构

if [ condition ]; then
    # 条件成立时执行
else
    # 条件不成立时执行
fi

✅ 多分支结构

if [ condition1 ]; then
    # 条件1成立时执行
elif [ condition2 ]; then
    # 条件2成立时执行
else
    # 所有条件都不成立时执行
fi

💡 fiif 的反向拼写,用于结束 if 语句块。


二、使用 [ ] 进行条件判断

这是最基础的写法,兼容所有 POSIX shell(如 dash、bash)。

✅ 示例:

a=10
b=20

if [ $a -gt $b ]; then
    echo "✅ a > b"
else
    echo "❌ a <= b"
fi

⚠️ 注意:

  • [ ] 中的每个表达式必须用空格隔开。
  • 使用 -eq, -gt 等操作符来比较整数。
  • 使用 === 比较字符串。
  • 必须对变量加引号以防止空格或未定义变量导致错误。

三、使用 [[ ]] 更强大更安全

[[ ]] 是 Bash 的扩展特性,支持更复杂的逻辑和正则匹配。

✅ 示例:

name="Alice"

if [[ $name == A* ]]; then
    echo "✅ 名字以 A 开头"
fi

if [[ $name =~ ^[A-Z][a-z]+$ ]]; then
    echo "✅ 名字格式正确:首字母大写,其余小写"
fi

✅ 支持通配符和正则表达式

特性 示例
通配符匹配 [[ $str == *.log ]]
正则匹配 [[ $str =~ ^error.*$ ]]

四、文件相关判断实战

✅ 判断文件是否存在并可读

file="/etc/passwd"

if [ -f "$file" ]; then
    echo "✅ $file 是普通文件"
    if [ -r "$file" ]; then
        echo "✅ 并且可读"
    else
        echo "❌ 不可读"
    fi
else
    echo "❌ 文件不存在"
fi

✅ 自动创建备份目录

backup_dir="/home/ubuntu/backups"

if [ ! -d "$backup_dir" ]; then
    mkdir -p "$backup_dir"
    echo "📁 备份目录已创建"
fi

五、字符串判断实战

✅ 用户登录验证脚本

read -p "请输入用户名:" username
read -sp "请输入密码:" password

valid_user="admin"
valid_pass="123456"

if [ "$username" = "$valid_user" ] && [ "$password" = "$valid_pass" ]; then
    echo -e "\n✅ 登录成功!欢迎 $username"
else
    echo -e "\n❌ 登录失败,请重试"
fi

六、整数比较实战

✅ 判断年龄范围

read -p "请输入您的年龄:" age

if [ -z "$age" ]; then
    echo "❌ 错误:请输入有效的年龄"
    exit 1
fi

if [ $age -lt 0 ]; then
    echo "❌ 错误:年龄不能为负数"
elif [ $age -lt 18 ]; then
    echo "👶 您未成年"
elif [ $age -lt 60 ]; then
    echo "🧑‍💼 您处于工作年龄段"
else
    echo "👵 您已退休"
fi

七、布尔逻辑与组合判断

✅ 判断服务状态 + 日志大小

logfile="/var/log/app.log"
max_size=1024   # KB

if [ -f "$logfile" ]; then
    size=$(du -k "$logfile" | awk '{print $1}')
    if [ $size -gt $max_size ]; then
        echo "🗑️ 日志过大,正在清理..."
        > "$logfile"
    else
        echo "✅ 日志正常,无需清理"
    fi
else
    echo "⚠️ 日志文件不存在"
fi

八、不同系统的差异与注意事项 ⚠️

项目 Bash Dash (Ubuntu 默认) zsh
支持 [[ ]] ❌(部分支持)
支持正则匹配 =~
支持通配符 == *.log
推荐脚本开头 #!/bin/bash #!/bin/sh #!/bin/zsh
推荐写法 使用 [[ ]] 使用 [ ] 使用 [[ ]]

📝 小贴士:

  • 在 Ubuntu 系统中,默认 /bin/shdash,不支持 [[ ]],所以如果你要使用高级特性,请确保脚本开头为 #!/bin/bash
  • 使用 [ ] 时务必注意变量是否为空,建议始终加双引号。

九、完整案例:系统健康检查脚本 🧪

#!/bin/bash

# 检查磁盘空间
used=$(df -h / | awk 'NR==2 {print $3}' | sed 's/G//')
total=$(df -h / | awk 'NR==2 {print $2}' | sed 's/G//')

percent=$(echo "scale=2; ($used / $total) * 100" | bc)

if (( $(echo "$percent > 90" | bc -l) )); then
    echo "🔴 警告:磁盘使用率超过 90%!当前为 ${percent}%"
elif (( $(echo "$percent > 70" | bc -l) )); then
    echo "🟡 提示:磁盘使用率为 ${percent}%"
else
    echo "🟢 磁盘使用率正常:${percent}%"
fi

# 检查 nginx 是否运行
if pgrep -x "nginx" > /dev/null; then
    echo "✅ Nginx 正在运行"
else
    echo "❌ Nginx 未运行"
fi

⚠️ 常见陷阱 & 解决方案

问题 原因 解决方法
[: unary operator expected 变量未赋值或为空 使用双引号 " " 包裹变量
integer expression expected 比较字符串而非整数 使用 -eq 之前确保变量为数字
unexpected operator 使用了 > < 等符号 应使用 -gt -lt
[[ 报错 系统 shell 不是 bash 确保脚本开头为 #!/bin/bash
文件路径含空格 未加引号导致解析错误 始终用双引号包裹路径变量

🧠 总结与小贴士

技巧 说明
if 是 Shell 的“大脑” 控制脚本走向的核心工具
推荐使用 [[ ]] 更安全、功能更强
始终对变量加双引号 防止未定义或含空格出错
使用 $? 检查结果 调试时非常有用
结合 test 构建复杂逻辑 让脚本具备“思考能力”
善用正则匹配和通配符 提升灵活性
避免直接使用 test 命令 推荐使用 [ ][[ ]]

📚 推荐练习题(可选)

  1. 编写一个脚本,判断某个服务(如 nginx)是否运行,如果没有就启动它。
  2. 写一个脚本,检查 /tmp 目录下是否有 .tmp 文件,如果有则删除。
  3. 实现一个简易计算器,接收两个参数和一个运算符(+、-、*、/),输出结果。
  4. 编写一个脚本,判断当前用户是否为 root,不是则提示并退出。
  5. 创建一个日志分析脚本,统计某日志中包含 “error” 的行数。

🎯 下一章预告:《Shell 流程控制 —— for、while、until 循环》

你已经掌握了如何进行条件判断与分支控制,下一步我们将学习如何让脚本重复执行某些任务 —— 使用 for, while, until 等循环结构,让你的脚本真正“动起来”!

需要我继续为你生成下一章内容吗?😊

posted @ 2023-04-02 21:45  红尘过客2022  阅读(75)  评论(0)    收藏  举报