应使用 root 权限编辑 crontab(sudo crontab -e),用绝对路径调用命令,配合 -daystart 和 -type f 精准清理日志,避免与 logrotate 冲突,并注意 cron 环境变量差异。

crontab -e 编辑时权限不对,脚本根本不会执行
很多人直接用普通用户运行 crontab -e,然后写了一堆 rm /var/log/*.log.* 这类命令,结果发现日志没删——因为普通用户没权限删系统日志目录下的文件。crontab 任务默认以当前用户身份运行,不自动提权。
实操建议:
- 如果必须清理
/var/log/下的文件,改用 root 用户编辑定时任务:sudo crontab -e - 避免在 crontab 行里直接写
sudo rm ...:cron 不读取你的交互式 sudo 权限缓存,会卡在密码提示或静默失败 - 脚本本身也不应依赖交互式环境,所有路径写绝对路径,比如用
/bin/find而不是find
find + -mtime 和 -delete 组合容易误删或漏删
-mtime +7 看似是“7天前”,实际含义是“修改时间大于 7×24 小时”,即至少 168 小时 + 1 秒才算匹配。如果你每天凌晨 2 点执行,而某日志最后修改是昨天下午 3 点,它要到后天下午 3 点才被识别为 “+7 天”——导致延迟一天。
更稳妥的做法是用 -daystart(让时间计算从当日 00:00 开始),并配合 -type f 明确只处理文件:
/bin/find /var/log/nginx -type f -name "*.log.*" -daystart -mtime +7 -delete
注意:
-
-delete是 find 的动作,不是外部命令,效率高但不可逆;调试阶段先换成-print看会删哪些文件 - 某些老版 find(如 CentOS 6)不支持
-delete,得用-exec rm {} \;,性能略差且需注意花括号和分号的转义 - 别对
/var/log/根目录无差别扫,优先限定子目录(如/var/log/nginx、/var/log/myapp)
crontab 时间格式写错,任务从不触发
常见错误包括:把周几和月份位置颠倒、用中文空格、漏掉必要字段、误以为 */5 * * * * 是“每 5 分钟一次”(其实是“每分钟都执行”,因为 */5 在分钟位表示“0,5,10,...,55 分”才对)。
推荐写法(每天凌晨 2:15 清理):
15 2 * * * /bin/find /var/log/nginx -type f -name "*.log.*" -daystart -mtime +7 -delete
验证方式:
- 用
crontab -l确认内容已保存 - 临时改成
* * * * *(每分钟执行),配合echo $(date) >> /tmp/cron-test.log看是否真在跑 - 检查系统 cron 服务是否启用:
systemctl is-active cron(Ubuntu/Debian)或systemctl is-active crond(RHEL/CentOS)
日志轮转(logrotate)和手动清理脚本共存会冲突
很多服务(如 nginx、rsyslog)已配了 logrotate,它会在固定时间压缩、删除旧日志。如果你另起 crontab 脚本也去删同一批文件,可能删掉 logrotate 还没处理完的临时文件,或重复压缩已归档的日志。
判断是否已有 logrotate 管理:
- 查配置:
ls /etc/logrotate.d/ | grep -E "(nginx|myapp)" - 看日志状态:
logrotate -d /etc/logrotate.conf(dry-run 模式模拟执行) - 如果已有 logrotate,优先调整它的配置(如改
rotate 30或加maxage 7),而不是另起 cron - 若必须自定义清理,确保路径不重叠,例如 logrotate 管
/var/log/nginx/access.log,你脚本只清/var/log/nginx/archive/下的备份
实际部署时最常被忽略的是环境变量差异:crontab 执行时的 $PATH 很窄(通常只有 /usr/bin:/bin),所以 python3 或 jq 这类非基础命令大概率找不到。要么全用绝对路径(/usr/bin/python3),要么在脚本开头显式设置 PATH。


















