第 35 课:if 条件判断
学习目标
完成本课学习后,你将能够:
- 理解 Shell 脚本中 if 条件判断的基本语法和结构
- 掌握文件与目录的常见测试操作(如是否存在、是否可读等)
- 学会使用逻辑运算符组合多个条件
- 能够编写包含条件判断的简单运维脚本
核心概念
1. 什么是条件判断?
想象一下,你在写一个自动备份脚本:如果 /backup 目录不存在,就创建它;如果存在,就直接开始备份。这种“如果…就…”的逻辑,就是条件判断。在 Shell 脚本中,我们使用 if 语句来实现这个功能。
2. 基本语法结构
Shell 的 if 语句有几种形式,最常用的是:
if [ 条件 ]; then
# 条件为真时执行的命令
fi
或者:
if [ 条件 ]; then
# 条件为真时执行的命令
else
# 条件为假时执行的命令
fi
还有更复杂的:
if [ 条件1 ]; then
# 条件1为真时执行
elif [ 条件2 ]; then
# 条件1为假且条件2为真时执行
else
# 所有条件都为假时执行
fi
重要提醒:[ 后面和 ] 前面必须有空格!这是初学者最容易犯的错误。
3. 文件与目录测试
在运维中,我们经常需要检查文件或目录的状态。以下是一些常用测试:
| 测试条件 | 含义 | 示例 |
|---|---|---|
-e | 文件/目录是否存在 | [ -e /etc/passwd ] |
-f | 是否为普通文件 | [ -f /etc/passwd ] |
-d | 是否为目录 | [ -d /home ] |
-r | 是否可读 | [ -r /etc/shadow ] |
-w | 是否可写 | [ -w /tmp ] |
-x | 是否可执行 | [ -x /usr/bin/ls ] |
-s | 文件是否非空(大小>0) | [ -s /var/log/syslog ] |
4. 字符串测试
[ "$str" = "hello" ] # 字符串相等
[ "$str" != "world" ] # 字符串不相等
[ -z "$str" ] # 字符串为空
[ -n "$str" ] # 字符串非空
5. 数值比较
[ 10 -eq 10 ] # 等于 (equal)
[ 10 -ne 20 ] # 不等于 (not equal)
[ 10 -gt 5 ] # 大于 (greater than)
[ 5 -lt 10 ] # 小于 (less than)
[ 10 -ge 10 ] # 大于等于 (greater or equal)
[ 5 -le 10 ] # 小于等于 (less or equal)
6. 逻辑运算符
我们可以用逻辑运算符组合多个条件:
# 逻辑与:两个条件都为真才为真
[ 条件1 ] && [ 条件2 ]
# 逻辑或:至少一个条件为真就为真
[ 条件1 ] || [ 条件2 ]
# 逻辑非:条件取反
[ ! 条件 ]
代码示例
示例 1:检查文件是否存在并给出提示
#!/bin/bash
# 文件名:check_config.sh
# 功能:检查配置文件是否存在
CONFIG_FILE="/etc/nginx/nginx.conf"
if [ -e "$CONFIG_FILE" ]; then
echo "配置文件存在:$CONFIG_FILE"
if [ -r "$CONFIG_FILE" ]; then
echo "配置文件可读,可以进行分析"
else
echo "警告:配置文件不可读,需要权限提升"
fi
else
echo "错误:配置文件 $CONFIG_FILE 不存在"
echo "请先安装 nginx 或创建配置文件"
exit 1
fi
# 如果文件存在且可读,可以继续后续操作
if [ -e "$CONFIG_FILE" ] && [ -r "$CONFIG_FILE" ]; then
echo "开始分析配置文件..."
# 这里可以添加分析配置文件的命令
fi
示例 2:磁盘空间监控脚本
#!/bin/bash
# 文件名:disk_monitor.sh
# 功能:监控磁盘空间使用率
# 获取根分区的使用百分比(去掉%号)
USAGE=$(df / | tail -1 | awk '{print $5}' | tr -d '%')
THRESHOLD=80
echo "当前磁盘使用率:${USAGE}%"
if [ "$USAGE" -gt "$THRESHOLD" ]; then
echo "警告:磁盘使用率超过 ${THRESHOLD}%!"
echo "建议清理 /var/log 目录下的旧日志文件"
# 检查是否还有足够的临时空间
if [ -d "/tmp" ] && [ -w "/tmp" ]; then
echo "临时目录 /tmp 可用,可以进行清理操作"
else
echo "错误:/tmp 目录不可用,请检查系统"
exit 1
fi
else
echo "磁盘空间充足,系统运行正常。"
fi
示例 3:用户权限检查脚本
#!/bin/bash
# 文件名:user_check.sh
# 功能:检查当前用户是否有执行特定操作的权限
# 检查是否以root用户运行
if [ "$(id -u)" -eq 0 ]; then
echo "当前以root用户运行"
echo "可以执行系统管理操作"
else
echo "当前用户:$(whoami)"
echo "非root用户,权限受限"
# 检查是否在sudo组中
if groups | grep -q "sudo\|wheel"; then
echo "但当前用户在sudo组中,可以使用sudo提升权限"
else
echo "警告:用户不在sudo组中,某些操作可能无法执行"
fi
fi
# 检查是否可以读取某个受保护的文件
SHADOW_FILE="/etc/shadow"
if [ -r "$SHADOW_FILE" ]; then
echo "可以读取shadow文件(可能权限配置有问题)"
elif [ -f "$SHADOW_FILE" ]; then
echo "shadow文件存在但不可读(正常)"
else
echo "shadow文件不存在(异常情况)"
fi
实践练习
练习 1:基础文件检查(简单)
题目:编写一个脚本,检查 /etc/hostname 文件是否存在。如果存在,显示其内容;如果不存在,创建一个新的主机名文件,内容为 "my-server"。
要求:
- 脚本文件名:
hostname_check.sh - 使用 if 条件判断
- 创建文件时需要使用 sudo 权限(提示:使用
sudo tee命令)
预期输出:
如果文件存在:
主机名文件存在,内容:my-server.example.com
如果文件不存在:
创建新的主机名文件:my-server
练习 2:目录清理脚本(中等)
题目:编写一个清理脚本,检查 /tmp 目录下是否有超过7天的日志文件(扩展名为 .log),如果有则删除它们,并统计删除的文件数量。
要求:
- 脚本文件名:
cleanup_logs.sh - 使用
find命令查找文件 - 在删除前显示找到的文件数量
- 使用 if 判断是否有文件需要清理
预期输出:
找到 3 个超过7天的日志文件
正在清理...
清理完成,共删除 3 个文件
或
没有找到需要清理的日志文件
练习 3:服务状态检查(较难)
题目:编写一个脚本检查 nginx 服务的状态。如果服务正在运行,检查其进程数是否超过10个;如果服务未运行,尝试自动启动它。
要求:
- 脚本文件名:
nginx_status.sh - 使用
pgrep nginx或systemctl检查服务状态 - 记录操作日志到
/var/log/nginx_check.log - 包含错误处理
预期输出:
nginx 服务正在运行,当前进程数:8
或
nginx 服务未运行,正在尝试启动...
nginx 服务启动成功
或
nginx 服务未运行,启动失败:端口80被占用
常见错误
1. 空格错误
# 错误写法 - 缺少空格
if [ -e"/etc/passwd" ]; then # 错误!
# 正确写法
if [ -e "/etc/passwd" ]; then # 正确
2. 变量未加引号
# 错误写法 - 如果变量为空会导致语法错误
if [ $FILE -e ]; then # 如果 $FILE 为空,实际执行 [ -e ]
# 正确写法 - 变量加双引号
if [ -e "$FILE" ]; then # 正确,即使变量为空也不会出错
3. 测试表达式错误
# 错误写法 - 使用了错误的数值比较
if [ $A > $B ]; then # 这是字符串重定向,不是数值比较!
# 正确写法
if [ $A -gt $B ]; then # 正确的数值比较
4. 混淆 Shell 类型
# 在某些 Shell 中可以使用双括号
if [[ $str == "hello" ]]; then # bash/zsh 支持
# 但在某些 Shell 中只能使用单括号
if [ "$str" = "hello" ]; then # 所有 Shell 都支持
5. 忘记结束标记
# 错误写法 - 缺少 fi
if [ 条件 ]; then
echo "条件为真"
# 正确写法
if [ 条件 ]; then
echo "条件为真"
fi # 不能忘记这个结束标记
小结
本课我们学习了 Shell 脚本中最重要的控制结构之一:if 条件判断。关键要点包括:
- 基本语法:记住
if [ 条件 ]; then ... fi的基本结构,注意空格 - 文件测试:使用
-e、-f、-d、-r、-w、-x等测试文件属性 - 字符串和数值:字符串用
=、!=、-z、-n;数值用-eq、-gt、-lt等 - 逻辑组合:
&&(与)、||(或)、!(非)组合多个条件 - 实际应用:条件判断是运维脚本的基础,用于错误检查、权限验证、资源监控等
记住:好的运维脚本应该“防患于未然”,在执行操作前先检查条件是否满足。这能大大提高脚本的健壮性和可靠性。
下一课我们将学习 case 语句,它适用于多分支选择场景,是 if 语句的有力补充。
练习编辑器
rust
Loading...