shell if else(完整教程)

Shell 脚本中的条件判断:掌握 if else 的核心逻辑

在日常的系统管理或自动化任务中,我们经常需要让脚本“思考”——根据不同的情况做出不同的反应。比如,检查某个服务是否运行,如果没运行就启动它;或者判断一个文件是否存在,再决定是否进行备份。这种“判断+执行”的能力,正是 shell 脚本中 if else 结构的核心价值。

你可以把 if else 想象成一个智能门卫:当有人靠近时,他会问“你是谁?”、“有没有权限?”——根据回答,决定放行还是拒绝。Shell 脚本中的条件判断,就是这么一个“逻辑决策器”,它让脚本不再是一条直线执行的流水线,而是具备了分支能力的智能程序。


条件判断的基本语法结构

在 Bash 脚本中,if else 的基本语法如下:

if [ 条件表达式 ]; then
    # 条件为真时执行的命令
    echo "条件成立,执行这里"
elif [ 另一个条件 ]; then
    # 上一个条件不成立,但这个成立时执行
    echo "第一个条件不成立,但第二个条件成立"
else
    # 所有条件都不成立时执行
    echo "所有条件都不成立,执行默认分支"
fi

⚠️ 注意:if 后面的 [ ] 是 test 命令的简写形式,必须与条件之间有空格,否则会报错。比如 [ -f file.txt ] 正确,[ -ffile.txt ] 错误。

关键点说明:

  • then 必须和 if 在同一行,或者用分号 ; 分隔。
  • elif 是 “else if” 的缩写,用于多条件判断。
  • fiif 的结束标记,必须写,否则脚本会语法错误。
  • 条件判断中,[ ] 两边必须有空格,这是 Shell 的语法要求。

常见的条件判断类型

if else 的威力来自于它能判断多种类型的状态。以下是几种最常用的判断方式:

文件与路径判断

判断文件是否存在、是否为目录、是否可读写等,是自动化脚本中最常见的需求。

if [ -f /etc/passwd ]; then
    echo "文件 /etc/passwd 存在"
else
    echo "文件 /etc/passwd 不存在"
fi

if [ -d /var/log ]; then
    echo "/var/log 是一个目录"
else
    echo "/var/log 不是目录"
fi

if [ -r /etc/hosts ]; then
    echo "当前用户有读取 /etc/hosts 的权限"
else
    echo "当前用户没有读取权限"
fi

📌 小贴士:-f 表示普通文件,-d 表示目录,-r 表示可读,-w 可写,-x 可执行。这些是 shell 中标准的测试操作符。


字符串比较

当你需要判断变量的值是否等于某个字符串时,可以使用 =!=

username="admin"

if [ "$username" = "admin" ]; then
    echo "欢迎管理员登录"
elif [ "$username" = "user" ]; then
    echo "欢迎普通用户"
else
    echo "未知用户"
fi

✅ 重要:变量必须用双引号包裹,防止变量为空或含空格时出错。例如,"$username"$username 更安全。


数值比较

数值比较使用 test 命令的专用符号:

  • -eq:等于
  • -ne:不等于
  • -lt:小于
  • -le:小于等于
  • -gt:大于
  • -ge:大于等于
score=85

if [ $score -ge 90 ]; then
    echo "成绩优秀,A 等级"
elif [ $score -ge 80 ]; then
    echo "成绩良好,B 等级"
elif [ $score -ge 70 ]; then
    echo "成绩合格,C 等级"
else
    echo "需要补考"
fi

💡 提示:数值比较不能用 ==>,必须使用上述专用操作符。> 在 shell 中是重定向符号,会出错!


实际应用案例:自动化备份脚本

下面是一个完整的 shell if else 应用示例:一个自动备份脚本。

#!/bin/bash

BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d)
TARGET="/home/user/data"
BACKUP_FILE="$BACKUP_DIR/backup_$DATE.tar.gz"

if [ ! -d "$TARGET" ]; then
    echo "错误:目标目录 $TARGET 不存在"
    exit 1
fi

if [ ! -w "$BACKUP_DIR" ]; then
    echo "错误:备份目录 $BACKUP_DIR 无写权限"
    exit 1
fi

echo "正在备份 $TARGET 到 $BACKUP_FILE..."

tar -czf "$BACKUP_FILE" -C "$(dirname "$TARGET")" "$(basename "$TARGET")"

if [ $? -eq 0 ]; then
    echo "备份成功!文件已保存至 $BACKUP_FILE"
else
    echo "备份失败!请检查权限或磁盘空间"
    exit 1
fi

🧠 说明:

  • $? 是上一条命令的退出状态码,0 表示成功,非 0 表示失败。
  • $(...) 是命令替换,用于动态获取值。
  • "-C" 指定 tar 命令的当前目录,避免路径问题。

这个脚本展示了 shell if else 如何层层递进地判断条件,确保每一步都安全可靠。


嵌套判断与逻辑组合

有时我们需要更复杂的判断逻辑,比如“如果文件存在且可读,才继续备份”。这时可以使用逻辑运算符:

  • !:逻辑非(取反)
  • -a:逻辑与(and)
  • -o:逻辑或(or)
file="/tmp/data.txt"

if [ -f "$file" ] && [ -r "$file" ]; then
    echo "文件存在且可读,可以处理"
elif [ -f "$file" ]; then
    echo "文件存在,但不可读"
else
    echo "文件不存在"
fi

📌 注意:&& 是 shell 中的逻辑与操作符,但不能在 [ ] 内部使用。必须用 [ ] 分开判断,再用 && 连接。


常见错误与调试技巧

错误 1:缺少空格

if [ -ffile.txt ]; then

if [ -f file.txt ]; then

错误 2:忘记引号

if [ $var = "test" ]; then

if [ "$var" = "test" ]; then

调试技巧:打印变量值

echo "变量值:$username"
echo "退出状态:$?"

使用 echo 可以快速查看变量内容和命令执行结果,是排查 shell if else 逻辑问题的利器。


总结:让脚本真正“聪明”起来

shell if else 并不是复杂的语法,但它赋予了脚本“思考”的能力。从判断文件存在,到处理用户输入,再到自动化运维任务,它无处不在。

掌握它,意味着你可以从“手动执行命令”迈向“编写智能脚本”。无论是系统维护、日志分析,还是持续集成流程,shell if else 都是你不可或缺的工具。

记住:条件判断不是“写完就完事”,而是要考虑所有可能的分支,并为每一种情况提供清晰的反馈。一个健壮的脚本,往往不是因为功能多,而是因为它“出错时知道怎么处理”。

现在,打开你的终端,试着写一个判断当前时间是否为工作日的脚本吧。让 shell if else 成为你写脚本时的第一个“思考起点”。