直接用crontab清理临时目录需显式声明PATH、分场景选策略、加日志与flock锁、测试验证后再上线,否则易静默失败。

直接用 crontab 清理临时目录,不能只写一条 find ... -delete 就完事。环境变量缺失、权限错位、时间逻辑混乱,很容易让任务静默失败——看着在跑,其实什么都没删。
环境变量必须显式声明
crontab 不加载 ~/.bashrc 或 /etc/profile,PATH 往往只有 /usr/bin:/bin。如果脚本里调用了 jq、rsync 或自定义二进制,大概率报 “command not found”。
- 在 crontab 条目开头加
PATH=/usr/local/bin:/usr/bin:/bin - 或在脚本第一行写
#!/bin/bash,第二行加source /etc/profile 2>/dev/null || true - 更稳妥的做法:所有命令用绝对路径,比如
/usr/bin/find、/bin/rm
临时目录清理要分场景选策略
不是所有临时目录都适合“一刀切 rm -rf”,不同位置风险等级和清理逻辑差异很大:
-
/tmp:系统级临时区,建议用systemd-tmpfiles --clean(读取/usr/lib/tmpfiles.d/*.conf),比裸 find 更安全;若坚持用 crontab,优先按修改时间(-mtime +3)而非访问时间(-atime),避免误删正在使用的文件 -
/var/log:应由logrotate主导管理;crontab 只作兜底,例如清理.gz或.old等已归档超过 30 天的残留文件 - 用户家目录下的
~/.cache、~/.thumbnails:用find -type d -empty -mtime +14 -delete清空空目录,再用find -type f -mtime +30 -delete清理老缓存,避免破坏当前会话的运行时缓存 - 自定义临时区(如
/data/tmp):明确限定类型,例如只删-name "*.tmp" -o -name "*.part",不碰其他扩展名
日志与锁机制不能省略
没有日志,你永远不知道任务是否真执行了;没有互斥控制,多个周期任务可能并发冲突,导致重复清理或中断失败。
- 每条 crontab 命令末尾加上
>> /var/log/clean-$(date +\%Y\%m).log 2>&1,按月轮转日志 - 对可能长时间运行的清理脚本,加
flock -n /tmp/clean-job.lock防重入,例如:flock -n /tmp/clean-job.lock -c 'bash /usr/local/bin/clean.sh' - 在脚本开头加
set -e,任一命令失败立即退出,避免后续误操作
测试再上线,别跳过验证环节
上线前必须手动模拟一次完整流程:
- 用
sudo -u www-data /bin/bash -c 'your_find_command_here'模拟目标用户执行环境 - 先用
-print替代-delete,确认输出全是预期目标文件 - 检查目标目录权限:
ls -ld /path/to/tmp,确保 crontab 执行用户有读+执行(进入目录)+写(删除)权限 - 查最近一次执行状态:
grep CRON /var/log/syslog | tail -10

















