crontab 不适合直接配置系统级定时数据同步任务,因其仅是调度器,真正决定系统级、可靠性与可审计性的关键是执行主体的身份、路径、环境及日志闭环。

crontab 不适合直接配置“系统级定时数据同步任务项”——它只是调度器,真正决定是否系统级、是否可靠、是否可审计的,是执行主体的身份、路径、环境和日志闭环。
下面分四个关键点讲清楚怎么做、为什么、以及最容易栽跟头的地方。
用 /etc/crontab 而不是 crontab -e
用户级 crontab -e 写的任务属于当前用户,即使你是 root,也受限于用户环境;而系统级同步(比如跨服务器拉日志、推数据库备份、同步 NFS 挂载点)必须明确指定执行用户、加载系统环境、并能被所有管理员统一维护。
正确做法是编辑 /etc/crontab,它的格式多一列:前五字段 + 用户名 + 命令:
0 2 * * * root /usr/bin/rsync -a --delete /var/log/nginx/ user@backup-server:/backups/nginx/
注意:/etc/crontab 中每行必须包含用户名字段(如 root),否则会静默忽略该行。
- 不要在
/var/spool/cron/root里写系统任务——它不体现“谁在跑”,也不方便审计 -
/etc/cron.d/可以用,但文件名不能含点(.conf不行)、必须有所有权(root:root)、权限为644,否则crond直接跳过
rsync 或 scp 命令必须用绝对路径 + 全参数显式控制
系统级同步失败最常见原因:命令找不到、SSH key 不可用、路径不存在、没处理 exit code。
crond 的 PATH 默认极窄(/usr/bin:/bin),所以 rsync 必须写成 /usr/bin/rsync,不能只写 rsync;同理,ssh 配置路径、私钥路径也要绝对化。
Zynq‑7000 / Zynq UltraScale+ 硬件调试技能。适用于 Xilinx Zynq(Cortex‑A9/A53 + FPGA)Linux 环境,调试 I2C、I2S、UART、GPIO 等外设。包括设备树配置、内核驱动、用户空间调试工具、交叉编译和常见问题排查,支持 PetaLinux 开发。
示例(带错误防护):
15 3 * * * root /usr/bin/rsync -avz --delete -e "/usr/bin/ssh -i /root/.ssh/sync_key" /data/export/ user@dst:/import/ >> /var/log/sync-data.log 2>&1 || echo "$(date): rsync failed" >> /var/log/sync-data.log
- 务必加
--delete(如果需要)并确认源/目标目录末尾斜杠语义一致 - 用
-e指定 SSH 参数,避免依赖~/.ssh/config(crond不读这个) - 最后一段
|| echo ...是兜底——很多任务失败后没日志,靠这个至少知道“挂了”
同步前加锁,避免并发冲突
如果同步脚本执行时间波动大(比如网络抖动导致某次耗时 8 分钟),而 cron 设置为每 5 分钟一次,就可能多个 rsync 进程同时操作同一目录,轻则覆盖,重则损坏。
简单可靠的加锁方式是用 flock:
0 3 * * * root /usr/bin/flock -n /tmp/sync-data.lock -c '/usr/bin/rsync -a /src/ user@dst:/dst/ >> /var/log/sync.log 2>&1'
-
-n表示非阻塞:如果锁已被占,直接跳过本次,不卡住后续任务 - 锁文件路径必须是全局可写的(
/tmp/安全),且不能放在 NFS 或 tmpfs 上(部分实现不支持) - 不要用
mkdir或touch自己实现锁——竞态条件难防
日志必须独立、可轮转、带时间戳
把输出重定向到 /var/log/xxx.log 是底线,但还不够。系统级任务日志要满足三个条件:不丢、不爆、可查。
推荐组合:
- 日志路径用绝对路径,如
/var/log/data-sync.log(别用~/或相对路径) - 配合
logrotate管理,新建/etc/logrotate.d/data-sync:
/var/log/data-sync.log {
daily
missingok
rotate 30
compress
delaycompress
notifempty
}- 在 crontab 命令里加
$(date +\%Y-\%m-\%d\ \%H:\%M):\手动打时间戳(crond自带的时间戳只在/var/log/cron里,不进你的日志)
最常被忽略的一点:crond 对 stderr 的默认处理是发邮件给任务用户。若没配本地邮件服务(sendmail 或 ssmtp),错误就彻底消失。所以 2>&1 重定向不是可选项,是必选项。

















