shell 脚本条件判断与循环速成
发布时间:2026-05-15 09:37       
更新时间:2026-05-16 04:39
学 shell 的条件判断与循环,拿清理日志当练习题最合适:逻辑真实、风险可控、每天用得上。目标脚本能按策略清理旧日志,用到 if、for、case 三件套。
## if:判断目录与文件
```
#!/bin/bash
LOG_DIR=/var/log/myapp
if [ ! -d "$LOG_DIR" ]; then
echo "目录不存在: $LOG_DIR"
exit 1
fi
```
[ 与内容之间必须有空格;判断文件用 -f、目录用 -d、判空串用 -z。数字比较用 -gt、-lt,字符串比较用 = 和 !=,两类别混。双中括号 [[ ]] 是 bash 的增强版,支持 &&、|| 直接连写还能少踩引号的坑,新脚本可以优先用它;单中括号的好处是兼容 sh。选择标准一句话:确定机器上是 bash,就用双中括号;脚本要交给 sh 跑,就用单中括号。
## for:遍历目录逐个处理
```
for f in "$LOG_DIR"/*.log; do
if [ -f "$f" ] && [ $(stat -c %Y "$f") -lt $(date -d '7 days ago' +%s) ]; then
gzip "$f"
echo "已压缩: $f"
fi
done
```
glob 展开加引号防文件名带空格;stat -c %Y 取修改时间戳,与 7 天前的阈值比较;date -d '7 days ago' 是 GNU 写法,CentOS 与 Ubuntu 都通用。要按次数循环,用 C 风格写法:for ((i=0; i<5; i++)); do echo $i; done。遍历中想跳过某个文件,continue 直接进下一轮,break 整个跳出循环。嵌套循环里 break 只跳当前层,两层都要出来得写两个 break。
## case:按参数决定清理策略
```
case "$1" in
gzip) echo "执行压缩清理" ;;
delete) echo "执行删除清理" ;;
*) echo "用法: $0 {gzip|delete}"; exit 1 ;;
esac
```
$1 是第一个命令行参数,*) 分支兜底处理乱输入。参数多于一个时往后排 $2、$3,shift 命令可以让参数队列整体左移,处理不定长参数时常用。脚本入口有参数校验,才算能用。
## 验证动作
真跑之前先演习:把 gzip 换成 echo gzip,看会命中哪些文件,确认无误再执行;生产目录上先拿测试文件试一轮。删类操作永远比压类操作危险一档,多演习一轮不吃亏。写完还可以用 shellcheck 扫一遍脚本,常见的引号、变量问题它会逐条指出,脚本入库前跑一次是值得养成的习惯。清理类脚本建议同时满足两个条件才动手:文件超过指定天数、有 crontab 兜底每天跑。判断与循环就这几种写法,组合起来覆盖日常九成的批量操作。