crontab 备份失败主因是环境差异:path 缺失、不加载 shell 配置、home 错误;须用绝对路径、显式声明环境变量、重定向日志、避免交互特性,并验证每项假设。
crontab 里直接写备份命令为什么总失败
常见现象是脚本手动运行正常,放进 crontab 就没输出、没文件、甚至报 command not found。根本原因是 cron 环境极简:没有用户 shell 的 path、不加载 ~/.bashrc、home 可能不对。
- 所有命令用绝对路径,比如用
/usr/bin/rsync而不是rsync - 在 crontab 条目开头显式声明环境变量,例如:
PATH=/usr/local/bin:/usr/bin:/bin SHELL=/bin/bash HOME=/root - 重定向 stdout 和 stderr 到日志文件,方便排查:
0 2 * * * /usr/bin/bash /root/backup.sh >> /var/log/backup.log 2>&1 - 避免依赖交互式 shell 特性(如别名、函数),把逻辑全写进独立脚本里
备份脚本里用 rsync 还是 tar + scp
rsync 更适合增量同步,tar 更适合打包归档;选哪个取决于你要“同步状态”还是“保留快照”。生产中多数用 rsync,但要注意几个关键参数差异。
- 必须加
--delete才能清理目标端已删除的文件,但首次运行前先测试加--dry-run - 用
-a保时间戳和权限,但某些旧系统不支持,可拆成-rltgoD - 如果目标是远程服务器,优先走 SSH 密钥认证,禁止在命令里硬编码密码;密钥要用
-e "ssh -i /path/to/key"指定 - 大目录建议加
--bwlimit=5000(单位 KB/s)防带宽打满,影响线上服务
备份失败后怎么自动发通知
没人看日志就等于没监控。最轻量的办法是用 mail 或 curl 推送,但得避开常见陷阱。
- Linux 默认 mail 命令常依赖本地 MTA(如 sendmail),很多容器或精简系统压根没装;改用
curl调企业微信/钉钉 Webhook 更稳 - 只在出错时发通知:用
if ! your_backup_command; then notify_error; fi,别每次执行都刷屏 - 通知内容至少包含错误码和最近 10 行日志:
tail -n 10 /var/log/backup.log | curl -X POST -d "@-" https://oapi.dingtalk.com/... - Webhook 地址别写死在脚本里,用环境变量或配置文件隔离,避免泄露
保留最近 7 天备份但磁盘不爆掉
直接 rm -rf 旧目录风险高,find 命令参数稍错就删错;更安全的做法是让 rsync 自动管理,或用命名+轮转。
- 推荐按日期建子目录:
/backup/www_$(date +\%Y\%m\%d),再用find /backup -maxdepth 1 -name "www_*" -mtime +7 -delete - 注意
-mtime +7是“超过 7 天”,不是“7 天前”,测试时先换成-mtime +0看是否匹配当天目录 - 删除前加 dry-run 验证:
find ... -print先确认列表 - 如果备份目标是 NAS 或对象存储,优先用它们自带的生命周期策略,别靠脚本硬删
真正的难点不在调度或命令本身,而在于每个环节的假设是否成立——比如 cron 的 PATH、rsync 目标端磁盘空间、SSH 连接超时时间、甚至系统时区是否和计划任务预期一致。这些细节不验证,自动化就是定时自毁。










