推荐用 find 结合 -mtime +n 筛选过期日志,再通过 for 循环预览确认后删除,或直接用 find -exec / -delete 更安全高效;生产环境需加日志记录与错误处理。

在 Linux 中,用 for 循环清理过期日志文件是常见运维操作,关键在于准确识别“过期”(比如 30 天前)、安全匹配日志路径、并避免误删。下面给出实用、可直接调整的写法和注意事项。
明确日志文件范围和过期判断方式
日志通常存放在 /var/log/ 下,如 nginx/、apache2/ 或自定义目录。过期一般指修改时间(mtime)早于指定天数。Linux 的 find 命令比纯 for 更可靠地按时间筛选,因此推荐将 for 和 find 结合使用:
- 不用
ls -t | head -n等依赖列表顺序的方式——排序不稳定,且不反映真实时间 - 避免直接遍历所有
*.log文件再用stat判断——效率低、脚本复杂 - 优先用
find /path -name "*.log" -mtime +30找出 30 天前的文件,再交给for处理
安全删除的 for 循环写法(带预览和确认)
以下是一个兼顾安全与效率的示例(以清理 /var/log/myapp/ 下 30 天前的 .log 文件为例):
# 先预览将被删除的文件(不执行删除) for file in $(find /var/log/myapp/ -name "*.log" -mtime +30 2>/dev/null); do echo "即将删除: $file" done <h1>确认无误后,取消注释下一行并运行(或改用 -delete 更简洁)</h1><h1>for file in $(find /var/log/myapp/ -name "*.log" -mtime +30 2>/dev/null); do rm -f "$file"; done</h1><p></p>
-
2>/dev/null屏蔽权限不足等报错,避免干扰输出 - 变量加双引号
"$file"防止路径含空格时报错 - 首次务必先运行“预览”部分,检查路径和文件是否符合预期
更推荐:用 find -exec 替代 for(更简洁、更健壮)
其实多数场景下,find ... -exec rm {} \; 比 for 更合适,因为它天然规避了空格、换行、通配符扩展等问题:
# 安全删除(建议先加 -print 预览) find /var/log/myapp/ -name "*.log" -mtime +30 -print <h1>确认后执行删除</h1><p>find /var/log/myapp/ -name "*.log" -mtime +30 -delete </p>
-
-delete是 GNU find 特性,要求匹配条件在前(如-name和-mtime),且必须有写入权限 - 若系统不支持
-delete,可用-exec rm {} \;替代 - 该方式无需 shell 变量、无词法分割风险,适合自动化脚本
加入日志记录和错误处理(生产环境必备)
真正用于定时任务(如 cron)时,应记录操作痕迹并捕获异常:
#!/bin/bash LOG_DIR="/var/log/myapp" DAYS=30 LOG_FILE="/var/log/clean_logs_$(date +\%Y\%m\%d).log" <p>echo "[$(date)] 开始清理 $LOG_DIR 下 $DAYS 天前的日志..." >> "$LOG_FILE" find "$LOG_DIR" -name "*.log" -mtime +"$DAYS" -print -delete 2>&1 >> "$LOG_FILE" echo "[$(date)] 清理完成,共处理 $(wc -l > "$LOG_FILE" </p>
- 用
-print在删除前输出路径,便于审计 - 重定向
2>&1把错误也记入日志,方便排查权限或路径问题 - 脚本开头加
#!/bin/bash,确保在 cron 中正确执行











