find 命令配合 -mtime 是最直接的方案:-mtime +30 匹配修改时间超30天(即≥31天)的文件,需先用 -print 测试再加 -delete,注意路径、权限、命名覆盖及 logrotate 冲突。

find 命令配合 -mtime 是最直接的方案
Linux 下清理旧日志,find 是标准工具,-mtime +30 表示“修改时间超过 30 天”,注意是“大于 30”,不是“大于等于 30”——也就是说,30 天整的文件不会被匹配,要删满 31 天及以上的。
典型命令:
find /var/log/nginx/ -name "*.log.*" -type f -mtime +30 -delete
-
/var/log/nginx/是日志目录,按实际路径替换 -
"*.log.*"匹配切割后带扩展名的日志(如access.log.1、error.log.20240101),避免误删access.log当前活跃文件 -
-type f确保只处理普通文件,跳过目录或符号链接 -
-delete是find自带动作,比-exec rm {} \;更高效且原子安全
先测试再删除,避免误删
直接加 -delete 风险高,尤其第一次运行时。务必先用 -print 或 -ls 看清楚哪些文件会被删:
find /var/log/app/ -name "*.log.*" -type f -mtime +30 -print
如果输出看起来合理,再执行带 -delete 的版本。注意:-delete 隐含 -depth,所以不会因父目录先删导致子项报错,但依然不能替代人工确认。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 若日志用
logrotate管理,检查其配置中rotate和maxage是否已覆盖需求,重复清理可能冲突 - 某些系统(如 CentOS 6)的
find不支持-delete,得改用-exec rm {} +(注意结尾的+,比\;更省 fork 开销)
时间判断依据是 mtime,不是文件名里的日期
很多日志切割后重命名带日期(如 app.log.20231201),但 find -mtime 看的是文件最后修改时间(即切割完成那一刻的 mtime),不是文件名。只要切割过程没 touch 修改时间,就准确。
- 如果日志轮转脚本里用了
touch或cp --preserve=timestamps,mtime可能被篡改,这时需改用-printf '%T@ %p\n'查看真实时间戳验证 - 不推荐用
stat+awk解析文件名日期来删——逻辑复杂、易出错,且无法处理非标准命名(如.log.1、.log.2)
放进 cron 时要注意 PATH 和用户权限
crontab 默认 PATH 很窄(通常只有 /usr/bin:/bin),而 find 在 /usr/bin,一般没问题;但如果你在命令里调用了 date、logger 等,最好写绝对路径,或显式声明 PATH。
另外,确保 cron 运行用户对日志目录有读+执行(进入目录)权限,否则 find 会跳过该目录并报 Permission denied ——这个错误默认不输出到 cron 日志,容易以为没生效。
- 建议在 crontab 里加日志重定向:
0 2 * * * find /var/log/myapp/ -name "*.log.*" -type f -mtime +30 -delete >> /var/log/clean-logs.log 2>&1
- 如果日志目录属主是
root,而 cron 是普通用户跑的,要么提权(sudo不推荐进 cron),要么把清理任务放在 root 的 crontab 里
实际线上环境里,最常被忽略的是 -name 模式的覆盖范围:漏掉 .gz 压缩归档、或多级子目录(如 app/logs/2023/12/),这时候得加 -path 或用 -o 组合多个 -name。

















