1. Shell条件语句基础与测试操作
Shell脚本中的条件判断是自动化任务和系统管理的核心技能。任何条件判断都需要通过测试命令来执行,测试命令返回一个退出状态码:0表示真(条件成立),1表示假(条件不成立)。
1.1 测试命令的三种形式
在Shell中,我们有三种主要的测试命令形式:
- 传统test命令:
bash复制test 条件表达式
- 方括号形式(最常用):
bash复制[ 条件表达式 ] # 注意表达式与方括号之间的空格是必须的
- 双括号增强版(Bash扩展):
bash复制[[ 条件表达式 ]] # 支持更多功能如模式匹配和正则表达式
提示:现代脚本开发中推荐使用
[[ ]],因为它更安全且功能更强大。例如,它不需要对变量加引号来防止空值导致的语法错误。
1.2 文件测试操作
文件测试用于检查文件或目录的各种属性。这是系统管理脚本中最常用的测试之一。
常用文件测试操作符
| 操作符 | 作用描述 |
|---|---|
-e |
文件或目录是否存在 |
-f |
是否为普通文件 |
-d |
是否为目录 |
-r |
当前用户是否有读权限 |
-w |
当前用户是否有写权限 |
-x |
当前用户是否有执行权限 |
-s |
文件存在且大小大于0字节 |
-L |
是否为符号链接 |
-O |
当前用户是否为文件所有者 |
-G |
当前用户的组是否与文件相同 |
-nt |
文件是否比另一个文件新 |
-ot |
文件是否比另一个文件旧 |
文件测试实战示例
bash复制#!/bin/bash
# 文件属性检查脚本
check_file="/var/log/syslog"
backup_dir="/backup/logs"
# 检查文件是否存在
if [[ -e "$check_file" ]]; then
echo "[INFO] 文件 $check_file 存在"
# 检查文件类型
if [[ -f "$check_file" ]]; then
echo "[INFO] 这是一个普通文件"
elif [[ -d "$check_file" ]]; then
echo "[INFO] 这是一个目录"
fi
# 检查文件权限
[[ -r "$check_file" ]] && echo "[INFO] 文件可读"
[[ -w "$check_file" ]] && echo "[INFO] 文件可写"
[[ -x "$check_file" ]] && echo "[INFO] 文件可执行"
# 检查文件大小
if [[ -s "$check_file" ]]; then
file_size=$(du -h "$check_file" | cut -f1)
echo "[INFO] 文件非空,大小: $file_size"
else
echo "[WARNING] 文件为空"
fi
# 检查备份目录
if [[ ! -d "$backup_dir" ]]; then
echo "[ACTION] 备份目录不存在,正在创建..."
mkdir -p "$backup_dir"
chmod 750 "$backup_dir"
fi
# 检查文件是否可备份
if [[ -r "$check_file" && -w "$backup_dir" ]]; then
backup_file="${backup_dir}/syslog_$(date +%Y%m%d).bak"
cp "$check_file" "$backup_file"
echo "[SUCCESS] 文件已备份到 $backup_file"
else
echo "[ERROR] 无法备份文件 - 权限不足"
fi
else
echo "[ERROR] 文件 $check_file 不存在"
exit 1
fi
1.3 数值比较操作
数值比较在资源监控、阈值检查等场景非常有用。
数值比较操作符
| 操作符 | 描述 | 适用场景 |
|---|---|---|
-eq |
等于 | [ $a -eq $b ] |
-ne |
不等于 | [ $a -ne $b ] |
-gt |
大于 | [ $a -gt $b ] |
-ge |
大于等于 | [ $a -ge $b ] |
-lt |
小于 | [ $a -lt $b ] |
-le |
小于等于 | [ $a -le $b ] |
注意:在
(( ))算术表达式中可以使用更直观的数学比较符号:==,!=,>,>=,<,<=
数值比较实战示例
bash复制#!/bin/bash
# 系统资源监控脚本
# 获取系统指标
cpu_cores=$(nproc)
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4}' | cut -d. -f1)
mem_total=$(free -m | awk '/^Mem:/{print $2}')
mem_used=$(free -m | awk '/^Mem:/{print $3}')
mem_percent=$((mem_used*100/mem_total))
disk_usage=$(df / --output=pcent | tail -1 | tr -d '% ')
# 定义阈值
WARNING=80
CRITICAL=90
echo "====== 系统资源监控 ======"
echo "CPU核心数: $cpu_cores"
echo "CPU使用率: ${cpu_usage}%"
echo "内存使用: ${mem_used}MB/${mem_total}MB (${mem_percent}%)"
echo "根分区使用率: ${disk_usage}%"
# CPU检查
if (( cpu_usage >= CRITICAL )); then
echo "[CRITICAL] CPU使用率过高!"
# 找出占用CPU最高的进程
echo "占用CPU最高的进程:"
ps -eo pid,user,%cpu,cmd --sort=-%cpu | head -n 5
elif (( cpu_usage >= WARNING )); then
echo "[WARNING] CPU使用率偏高"
else
echo "[OK] CPU使用率正常"
fi
# 内存检查
if [[ $mem_percent -ge $CRITICAL ]]; then
echo "[CRITICAL] 内存使用率过高!"
# 找出占用内存最高的进程
echo "占用内存最高的进程:"
ps -eo pid,user,%mem,cmd --sort=-%mem | head -n 5
elif [[ $mem_percent -ge $WARNING ]]; then
echo "[WARNING] 内存使用率偏高"
else
echo "[OK] 内存使用率正常"
fi
# 磁盘检查
if [[ $disk_usage -ge $CRITICAL ]]; then
echo "[CRITICAL] 磁盘空间不足!"
# 找出占用空间最大的目录
echo "/目录下占用空间最大的目录:"
du -h / --max-depth=1 2>/dev/null | sort -hr | head -n 5
elif [[ $disk_usage -ge $WARNING ]]; then
echo "[WARNING] 磁盘空间紧张"
else
echo "[OK] 磁盘空间充足"
fi
1.4 字符串比较操作
字符串操作在用户输入验证、配置解析等场景非常关键。
字符串比较操作符
| 操作符 | 描述 | 示例 |
|---|---|---|
= / == |
字符串相等 | [[ $str1 == $str2 ]] |
!= |
字符串不等 | [[ $str1 != $str2 ]] |
-z |
字符串为空 | [[ -z $str ]] |
-n |
字符串非空 | [[ -n $str ]] |
