脚本不执行需先检查三件事:一是环境差异,cron默认用/bin/sh且path有限,脚本须指定#!/bin/bash并显式调用;二是命令必须用绝对路径;三是权限问题,系统级清理需root crontab而非普通用户加sudo。

crontab 里脚本不执行?先检查这三件事
绝大多数自动清理失败,不是逻辑错,而是 cron 环境和你终端不一致。它默认用 /bin/sh、$PATH 只有 /usr/bin:/bin,连 date -d 或 python3 都可能找不到。
- 脚本第一行必须是
#!/bin/bash(或#!/usr/bin/env bash),且 crontab 条目显式调用:0 2 * * * /bin/bash /usr/local/bin/clean.sh - 所有命令用绝对路径:
/usr/bin/find、/bin/rm、/usr/bin/journalctl,别写find或rm - 手动模拟 cron 环境测试:
env -i /bin/bash --noprofile --norc /usr/local/bin/clean.sh,这步跳过,90% 的“静默失败”就卡在这
清理逻辑别信文件名,用 -mtime 才可靠
靠解析 backup_20240501.tar.gz 里的日期判断过期,极易出错:文件被 touch 修改时间、命名不统一、时区偏差,都会导致误删或漏删。
- 真正可信的是文件最后修改时间(即备份完成时间):
/usr/bin/find /backup -name "*.tar.gz" -mtime +7 -delete—— 注意-mtime +7表示“大于 168 小时”,即第 8 天起才删 - 需要更精确到小时?用
-mmin +4320(7 天 = 4320 分钟) - 调试阶段务必先用
-ls替代-delete,确认列出的确实是目标文件 - 加
-maxdepth 1防止递归进子目录;加-type f明确只处理文件
权限不对,删不动还不出错
普通用户 crontab 里执行 /bin/rm /var/log/nginx/*.log,大概率静默失败——因为没权限,rm 返回 Permission denied,但 cron 默认丢弃 stderr,你看不到任何提示。
- 系统级清理(如删
/var/log、/tmp、/var/cache/apt/archives/)必须用sudo crontab -e编辑 root 任务,别在 crontab 行里写sudo rm(无效) -
/etc/cron.d/下的文件必须带用户名字段,例如:30 3 * * * root /usr/bin/find /tmp -type f -mtime +7 -delete - 脚本里涉及写
/proc/sys/vm/drop_caches或改journald.conf,也必须以 root 身份运行
日志和锁机制不是可选项
没日志,失败你看不见;没锁,两个定时任务同时跑,可能删掉正在写的日志、清空一半的缓存,甚至把数据库临时文件删了。
- 每条 crontab 必须重定向输出:
0 2 * * * /usr/local/bin/clean.sh >> /var/log/clean.log 2>&1 - 加简单文件锁防并发:
if [ -f /tmp/clean.lock ]; then exit; else touch /tmp/clean.lock; trap "rm -f /tmp/clean.lock" EXIT; - 关键操作写审计日志:
logger -t clean-job "Deleted $(/usr/bin/find /tmp -type f -mtime +7 | wc -l) files"
实际配置时,最易被忽略的是环境隔离和时间基准——-mtime 看的是 inode 修改时间,不是文件名日期;而 cron 的 PATH 和 shell 默认值,和你在终端敲命令时根本不是一回事。











