用crontab实现关键应用备份需确保可靠、可验证、不干扰业务,重点在路径、环境、日志和防重叠四环节:脚本用绝对路径并显式指定解释器;环境变量需在crontab中定义;时间表达式注意“或”逻辑;必须重定向日志并加锁防并发;最后通过系统日志和服务状态验证生效。

用 crontab 实现关键应用备份,核心不是“加个定时就行”,而是确保备份动作可靠、可验证、不干扰业务。重点在路径、环境、日志和防重叠四个环节。
备份脚本必须用绝对路径并显式指定解释器
crontab 不读取你的 ~/.bashrc 或 PATH,默认只认 /usr/bin:/bin。脚本里写 python backup.py 或 ./run.sh 几乎必失败。
- 所有命令用全路径:比如 /usr/bin/python3 /opt/app/backup.py、/usr/bin/mysqldump
- 脚本第一行加 #!/bin/bash(或 #!/usr/bin/env bash),crontab 条目里也建议显式调用:/bin/bash /opt/app/backup.sh
- 如果脚本依赖自定义环境变量(如 JAVA_HOME、BACKUP_DIR),在 crontab 条目最前面定义:
JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 BACKUP_DIR=/data/backup 0 2 * * * /bin/bash /opt/app/backup.sh
时间表达式要匹配真实备份需求,避免逻辑误读
常见误区是把“日期”和“星期”当成“且”关系。其实 cron 是“或”:只要满足任一条件就触发。比如 0 2 15 * 6 表示“每月15号 或 每周六凌晨2点”,不是“15号且周六”。
- 每天固定时间备份(如凌晨2:00):0 2 * * *
- 工作日备份(周一至周五):0 2 * * 1-5 或 0 2 * * 1,2,3,4,5
- 每月1号 + 每周六都备份:0 2 1 * *,0 2 * * 6(两行)
- 避开周末的每月1号备份?cron 本身做不到“且”,得在脚本里判断:
0 2 1 * * /bin/bash -c 'if [ $(date +\%u) -le 5 ]; then /opt/app/backup.sh; fi'
必须重定向输出并加锁防并发
不记录日志=无法排查;不加锁=两次备份同时写同一目录,可能损坏归档文件或填满磁盘。
- 每条 crontab 任务末尾加上:>> /var/log/backup.log 2>&1,便于追踪成功与否
- 脚本开头加简单文件锁:
LOCKFILE=/tmp/backup.lock
if [ -f "$LOCKFILE" ]; then exit 1; fi
touch "$LOCKFILE"
trap 'rm -f "$LOCKFILE"' EXIT - 更稳妥可用 flock:
0 2 * * * flock -n /tmp/backup.lock -c '/opt/app/backup.sh >> /var/log/backup.log 2>&1'
验证是否真正生效,不能只看 crontab -l
看到任务列出来 ≠ 它会跑。必须查系统级证据:
- 确认服务在运行:systemctl status cron(Ubuntu/Debian)或 systemctl status crond(CentOS/RHEL)
- 查 cron 日志:grep CRON /var/log/syslog(Ubuntu)或 journalctl -u crond -n 30(CentOS)
- 临时设成每分钟执行一次(* * * * *),等两分钟看日志有没有 (user) CMD (…) 记录
- 测试脚本本身能否无交互运行:sudo -u youruser /bin/bash -c '/opt/app/backup.sh >> /tmp/test.log 2>&1'











