shell if 判断(实战指南)

Shell if 判断:让脚本学会“思考”

在写 Shell 脚本时,你有没有遇到过这样的场景:
你希望脚本能根据某个条件来决定下一步该做什么?比如,检查某个文件是否存在,如果存在就备份,否则就提示用户。这时候,shell if 判断 就是你的“大脑”——它让脚本不再只是按部就班地执行命令,而是具备了“判断能力”。

这就像你去食堂打饭:

  • 如果窗口还有红烧肉,你就打一份;
  • 如果没有,你就换一个菜。

Shell 脚本也一样,它需要根据条件“做选择”。而 if 语句,就是实现这种选择的核心语法。


if 判断的基本语法结构

shell if 判断 的基本结构非常清晰,就像写一个简单的“如果……就……”句子。它的标准格式如下:

if [ 条件表达式 ]; then
    # 条件为真时执行的命令
    echo "条件成立,执行这里"
fi

注意几点:

  • if[ 之间必须有空格。
  • [ 和条件之间也要有空格。
  • then 后面要换行或用分号 ; 连接。
  • fiif 的结束标志,像“括号闭合”一样不能少。

示例:判断数字大小

num=85

if [ $num -gt 80 ]; then
    echo "成绩优秀!"
fi

注释:

  • $num 表示变量 num 的值。
  • -gt 是“大于”的比较运算符,用于整数比较。
  • [ 是 test 命令的简写,用于判断条件真假。
  • 执行结果会输出 “成绩优秀!” 因为 85 > 80。

常见的条件判断类型

shell if 判断 中,我们常会遇到以下几类判断:

数值比较

用于比较两个整数的大小,常见运算符如下:

操作符 含义
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
score=70

if [ $score -lt 60 ]; then
    echo "成绩不及格"
elif [ $score -lt 80 ]; then
    echo "成绩及格"
else
    echo "成绩优秀"
fi

注释:

  • elif 是“else if”的缩写,用于多个条件分支。
  • 这里先判断是否小于 60,否则再判断是否小于 80,否则默认为优秀。
  • 输出结果为 “成绩及格”。

字符串比较

判断两个字符串是否相等,或是否为空,使用 =!=

name="Alice"

if [ "$name" = "Alice" ]; then
    echo "欢迎 Alice!"
fi

注释:

  • 双引号 " 保护变量,防止空值或含空格时出错。
  • 使用 = 比较字符串内容。
  • 注意:= 两边要有空格,否则会报错。

文件状态判断

这是 shell if 判断 中最实用的一类,常用于脚本自动化中。

判断条件 含义
-f 文件是否存在且是普通文件
-d 目录是否存在
-r 文件可读
-w 文件可写
-x 文件可执行
-z 字符串为空
-n 字符串非空
config_file="/etc/myapp/config.conf"

if [ -f "$config_file" ]; then
    echo "配置文件存在,正在加载..."
else
    echo "配置文件不存在,创建中..."
    touch "$config_file"
fi

注释:

  • -f 判断是否为普通文件(不是目录或设备)。
  • touch 命令用于创建空文件。
  • 使用双引号避免路径含空格时出错。

多条件判断:逻辑与、或、非

在实际脚本中,往往需要同时满足多个条件。这时,shell if 判断 支持逻辑运算:

  • &&:逻辑“与”(两个条件都成立)
  • ||:逻辑“或”(至少一个成立)
  • !:逻辑“非”(取反)

示例:检查用户权限与文件存在

if [ "$(whoami)" = "root" ] && [ -f "/etc/app.conf" ]; then
    echo "权限充足,可执行操作"
else
    echo "权限不足或配置文件缺失"
fi

注释:

  • $(whoami) 是命令替换,获取当前用户名。
  • && 表示两个条件必须同时成立。
  • 如果不是 root 用户,或文件不存在,都会进入 else 分支。

使用 ! 取反

if ! [ -f "backup.tar.gz" ]; then
    echo "备份文件不存在,开始打包..."
    tar -czf backup.tar.gz /data
fi

注释:

  • ! 表示“非”,即条件为假时才执行。
  • 这里等价于 if [ ! -f "backup.tar.gz" ],但显式写出更清晰。

使用 [[ ]] 替代 [ ] 的优势

虽然 [ 是传统写法,但推荐使用 [[ ]],因为它更安全、功能更强,尤其在处理字符串和正则时。

优势对比:

特性 [ ] [[ ]]
支持正则匹配 不支持 支持 =~ 操作符
支持字符串比较 =!= 支持 ==!=
支持逻辑运算 必须用 && 和 `
变量引号省略 必须加双引号 可选(但建议加)

示例:使用 [[ ]] 进行正则匹配

email="user@example.com"

if [[ $email =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
    echo "邮箱格式正确"
else
    echo "邮箱格式错误"
fi

注释:

  • =~[[ ]] 中的正则匹配操作符。
  • 正则表达式匹配常见邮箱格式。
  • 使用 [[ ]] 更简洁,无需担心引号问题。

实战案例:自动备份脚本

我们来写一个完整的 shell if 判断 实战脚本,实现“每天凌晨自动备份数据库”。

#!/bin/bash

backup_dir="/backup"
db_name="myapp_db"
backup_file="$backup_dir/$(date +%Y%m%d).sql"

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

if ! command -v mysqldump &> /dev/null; then
    echo "错误:mysqldump 命令未安装"
    exit 1
fi

echo "开始备份数据库:$db_name"
mysqldump -u root -p123456 $db_name > "$backup_file"

if [ $? -eq 0 ]; then
    echo "备份成功,文件已保存:$backup_file"
else
    echo "备份失败!"
    exit 1
fi

注释:

  • command -v 用于检查命令是否存在。
  • $? 是上一条命令的退出状态码,0 表示成功。
  • exit 1 表示脚本终止并返回错误码。
  • 这个脚本完整展示了 shell if 判断 在真实项目中的应用。

常见错误与调试技巧

在使用 shell if 判断 时,初学者容易犯几个错误:

  1. 忘记空格

    if [ $a=5 ]  # ❌ 错误,[ 和 = 之间没空格
    

    应改为:

    if [ $a = 5 ]  # ✅ 正确
    
  2. 变量未加引号

    if [ -f $file ]  # ❌ 如果文件名含空格会出错
    

    应改为:

    if [ -f "$file" ]  # ✅ 安全写法
    
  3. 使用 = 比较字符串时漏掉引号

    if [ "$name" = "Alice" ]  # ✅ 正确
    

调试建议:

  • 使用 set -e 让脚本在出错时立即退出。
  • 使用 echo 打印变量值,确认条件是否按预期执行。
  • 在复杂逻辑中,先用 echo 输出判断条件,再执行 if

总结

shell if 判断 是 Shell 脚本的“灵魂”,它让脚本从“死板执行”变成“智能决策”。无论是判断文件是否存在、数值大小,还是组合多个条件,它都能胜任。

掌握它,你就拥有了编写自动化脚本的能力。从简单的条件判断,到复杂的备份、部署、监控脚本,shell if 判断 都是不可或缺的基础。

记住:

  • 条件判断要加空格。
  • 变量尽量用双引号包裹。
  • 复杂逻辑优先使用 [[ ]]
  • 多用 echo 调试,避免“黑箱运行”。

当你能熟练运用 shell if 判断,你会发现,Shell 脚本不再只是命令的堆砌,而是一套真正可维护、可扩展的自动化工具。