1. Shell条件语句基础认知
在Linux系统管理和自动化脚本编写中,条件判断是构建智能脚本的基石。不同于其他编程语言,Shell的条件语句有其独特的语法结构和实现方式,这也是许多初学者容易踩坑的地方。我至今记得第一次写Shell脚本时,因为少写了一个空格导致整个条件判断失效,排查了整整两小时才找到问题所在。
Shell条件语句的核心作用是根据不同条件执行不同的代码块,这就像交通信号灯控制系统——当满足特定条件(如某个变量值、文件状态或命令返回值)时,执行对应的操作流程。这种能力使得脚本可以处理复杂的逻辑判断,实现真正的自动化决策。
常见的条件判断场景包括:
- 检查文件/目录是否存在及其属性(可读、可写、可执行)
- 比较字符串内容或数值大小
- 验证命令执行结果(返回0表示成功,非0表示失败)
- 多条件组合判断(与、或、非逻辑运算)
关键提示:Shell脚本中条件语句的语法细节非常重要,特别是空格的使用。例如
[ $a -eq 10 ]中每个方括号前后都必须有空格,这是Shell语法解析的硬性要求。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 条件语句类型详解
2.1 if-then-fi基础结构
最基本的if语句结构如下:
bash复制if [ condition ]; then
# 条件为真时执行的命令
fi
这里的[ condition ]实际上是调用test命令的另一种写法,也可以直接使用test命令:
bash复制if test condition; then
# 命令序列
fi
实际案例:检查文件是否存在
bash复制#!/bin/bash
file="/path/to/file"
if [ -f "$file" ]; then
echo "文件存在且是普通文件"
fi
2.2 if-else扩展结构
当需要处理条件不成立的情况时,使用else分支:
bash复制if [ condition ]; then
# 条件为真
else
# 条件为假
fi
多层嵌套示例:
bash复制if [ "$USER" = "root" ]; then
echo "欢迎管理员"
elif [ "$USER" = "guest" ]; then
echo "欢迎访客"
else
echo "欢迎普通用户 $USER"
fi
2.3 case多分支语句
对于需要匹配多个模式的情况,case语句比多个if-elif更清晰:
bash复制case $变量 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
*)
默认命令序列
;;
esac
实际应用案例:
bash复制#!/bin/bash
read -p "输入y/n: " answer
case $answer in
[Yy]|[Yy][Ee][Ss])
echo "您选择了是"
;;
[Nn]|[Nn][Oo])
echo "您选择了否"
;;
*)
echo "无效输入"
;;
esac
3. 条件测试方法深度解析
3.1 文件测试操作符
Shell提供了丰富的文件测试操作符:
-e file:文件存在即为真-f file:是普通文件(非目录/设备文件)-d file:是目录-r file:可读-w file:可写-x file:可执行-s file:文件大小大于0-L file:是符号链接
示例组合使用:
bash复制if [ -f "/var/log/syslog" ] && [ -s "/var/log/syslog" ]; then
echo "系统日志存在且非空"
fi
3.2 字符串比较
字符串比较是Shell脚本中最容易出错的环节之一:
= 或 ==:字符串相等!=:字符串不等-z:字符串长度为0-n:字符串长度非0><:按字典顺序比较(需转义或使用双括号)
重要技巧:比较字符串时总是用引号包裹变量,防止变量为空时报错:
bash复制if [ "$str1" = "$str2" ]; then
echo "字符串相同"
fi
3.3 数值比较
数值比较需要使用特定的操作符:
-eq:等于-ne:不等于-gt:大于-ge:大于等于-lt:小于-le:小于等于
示例:
bash复制if [ $# -lt 1 ]; then
echo "至少需要一个参数"
exit 1
fi
3.4 复合条件
使用逻辑运算符组合多个条件:
!:逻辑非-a:逻辑与(同&&)-o:逻辑或(同||)
现代Shell推荐使用双括号语法:
bash复制if [[ $age -gt 18 && $age -lt 60 ]]; then
echo "适龄工作者"
fi
4. 高级条件判断技巧
4.1 双括号与双方格语法
(( ))用于算术运算,[[ ]]提供增强的条件测试:
bash复制# 算术比较
if (( $num1 > $num2 )); then
echo "$num1 大于 $num2"
fi
# 模式匹配
if [[ "$filename" == *.txt ]]; then
echo "文本文件"
fi
[[ ]]的优势:
- 支持通配符和正则匹配
- 字符串比较不需要引号
- 逻辑运算符更直观(&&, ||)
- 防止单词分割和路径扩展
4.2 命令执行状态判断
任何命令的退出状态都可以作为条件:
bash复制if grep -q "error" /var/log/syslog; then
echo "日志中包含错误信息"
fi
特殊变量$?获取上一条命令的退出状态:
bash复制command
if [ $? -eq 0 ]; then
echo "命令执行成功"
else
echo "命令执行失败"
fi
4.3 条件语句与函数结合
在函数中使用条件语句实现复杂逻辑:
bash复制check_disk() {
local usage=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
if (( usage > 90 )); then
return 1
else
return 0
fi
}
if ! check_disk; then
echo "磁盘空间不足!"
exit 1
fi
5. 实战案例与避坑指南
5.1 系统监控脚本示例
bash复制#!/bin/bash
# 检查CPU负载
load=$(uptime | awk -F'[a-z]:' '{print $2}' | cut -d, -f1 | tr -d ' ')
if (( $(echo "$load > 2.0" | bc -l) )); then
echo "警告:CPU负载过高 ($load)"
fi
# 检查内存使用
mem_free=$(free -m | awk '/Mem:/ {print $4}')
if [ $mem_free -lt 100 ]; then
echo "警告:可用内存不足 (${mem_free}MB)"
fi
# 检查磁盘空间
disk_usage=$(df -h / | awk 'NR==2 {print $5}' | tr -d '%')
if [ $disk_usage -gt 90 ]; then
echo "警告:根分区使用率 ${disk_usage}%"
fi
5.2 常见错误与解决方案
- 变量未引用的错误
bash复制# 错误写法(变量为空时会报错)
if [ $var = "value" ]; then
# 正确写法
if [ "$var" = "value" ]; then
- 比较运算符混淆
bash复制# 字符串比
