rsync配合cron需用绝对路径、转义%、先-n模拟运行:因cron环境变量缺失,rsync和ssh必须写全路径;%在crontab中须写成\%;--delete前务必用-n验证,末尾斜杠影响同步范围。

rsync 配合 cron 就能跑起来,不用装额外服务,但直接写进 crontab 容易失败——根本原因是环境变量缺失、路径不全、权限不对,不是命令本身有问题。
rsync 命令必须用绝对路径
cron 启动时的 PATH 极其有限(通常是 /usr/bin:/bin),很多发行版里 rsync 在 /usr/bin/rsync,但 ssh 可能在 /usr/bin/ssh 或 /usr/local/bin/ssh。
如果脚本里只写 rsync -av,cron 很可能报 command not found 或卡在 ssh: command not found。
- 用 which rsync 和 which ssh 查清真实路径
- 脚本中显式写成:/usr/bin/rsync -av -e "/usr/bin/ssh -o StrictHostKeyChecking=no" /src/ user@host:/dst/
- 不要依赖 $HOME:用 /home/username/ 这样的绝对路径代替 ~/cron 时间表达式里 % 要转义
想让备份文件名带日期,比如backup_20260708.tar.gz,常会写:rsync ... > /backup/backup_$(date +\%Y\%m\%d).log。
但 cron 把 % 当作换行符分隔符,未转义会导致命令截断、参数错乱,甚至把邮件发给 root。
- 所有 % 必须写成 \%(反斜杠转义)
- 正确写法:0 3 * * * /usr/bin/rsync -av /data/ /backup/ > /var/log/rsync.log 2>&1
- 如果要用 date,必须整个命令用单引号包裹或用脚本封装:0 3 * * * /bin/sh -c 'rsync -av /data/ /backup/ > /var/log/rsync_$(date +\%Y\%m\%d).log 2>&1'第一次启用 --delete 前一定要 -n 模拟运行
--delete 会让目标目录严格镜像源目录——源里删了的文件,目标里也会被删。这很危险,尤其当源路径多写一个空格或少个斜杠时。
- 先在脚本里加 -n(dry-run):
/usr/bin/rsync -avn --delete /data/ /backup/
- 手动执行一次,看输出里是不是真只删该删的、传该传的
- 确认无误后,再删掉 -n 上线
- 注意末尾斜杠:/data/ 同步内容;/data 同步整个目录——差一个字符,结果天壤之别
真正麻烦的不是写命令,而是环境隔离带来的隐性差异:你手动执行成功的命令,在 cron 里失败,大概率是因为它根本没加载你的 .bashrc,也不认识你设的 alias,连 ~ 都可能指向 /root 而不是你的家目录。把这些细节钉死,任务才能稳住。


















