Shell if 判断:让脚本学会“思考”
在写 Shell 脚本时,你有没有遇到过这样的场景:
你希望脚本能根据某个条件来决定下一步该做什么?比如,检查某个文件是否存在,如果存在就备份,否则就提示用户。这时候,shell if 判断 就是你的“大脑”——它让脚本不再只是按部就班地执行命令,而是具备了“判断能力”。
这就像你去食堂打饭:
- 如果窗口还有红烧肉,你就打一份;
- 如果没有,你就换一个菜。
Shell 脚本也一样,它需要根据条件“做选择”。而 if 语句,就是实现这种选择的核心语法。
if 判断的基本语法结构
shell if 判断 的基本结构非常清晰,就像写一个简单的“如果……就……”句子。它的标准格式如下:
if [ 条件表达式 ]; then
# 条件为真时执行的命令
echo "条件成立,执行这里"
fi
注意几点:
if和[之间必须有空格。[和条件之间也要有空格。then后面要换行或用分号;连接。fi是if的结束标志,像“括号闭合”一样不能少。
示例:判断数字大小
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 判断 时,初学者容易犯几个错误:
-
忘记空格:
if [ $a=5 ] # ❌ 错误,[ 和 = 之间没空格应改为:
if [ $a = 5 ] # ✅ 正确 -
变量未加引号:
if [ -f $file ] # ❌ 如果文件名含空格会出错应改为:
if [ -f "$file" ] # ✅ 安全写法 -
使用
=比较字符串时漏掉引号:if [ "$name" = "Alice" ] # ✅ 正确
调试建议:
- 使用
set -e让脚本在出错时立即退出。 - 使用
echo打印变量值,确认条件是否按预期执行。 - 在复杂逻辑中,先用
echo输出判断条件,再执行if。
总结
shell if 判断 是 Shell 脚本的“灵魂”,它让脚本从“死板执行”变成“智能决策”。无论是判断文件是否存在、数值大小,还是组合多个条件,它都能胜任。
掌握它,你就拥有了编写自动化脚本的能力。从简单的条件判断,到复杂的备份、部署、监控脚本,shell if 判断 都是不可或缺的基础。
记住:
- 条件判断要加空格。
- 变量尽量用双引号包裹。
- 复杂逻辑优先使用
[[ ]]。 - 多用
echo调试,避免“黑箱运行”。
当你能熟练运用 shell if 判断,你会发现,Shell 脚本不再只是命令的堆砌,而是一套真正可维护、可扩展的自动化工具。