掌握 Rsync:不止是文件同步,更是高效运维的基石

Rsync 是一个被低估的文件同步神器。本文将从基础语法讲起,深入探讨其核心选项、远程操作、自动化技巧以及常见陷阱,帮助你彻底掌握这个高效运维的利器。

阅读时长: 5 分钟
共 2210字
作者: eimoon.com

很多人可能觉得 scp 已经够用了,但如果你经常需要在服务器之间同步文件,特别是大文件或者整个目录,那 rsync 绝对是你的不二之选。rsync,全称 remote sync,远不止是一个简单的复制工具。它的杀手锏在于其"增量传输"(delta-transfer)算法。

简单来说,当你第二次同步同一个文件时,rsync 只会传输文件中发生变化的部分,而不是整个文件。这在备份、代码部署等场景下,能极大地节省带宽和时间。

这篇文章,我们就来彻底搞懂 rsync,从基础用法到一些高级技巧,让你在日常工作中用得得心应手。

Rsync 的基本语法与核心概念

rsync 的命令结构和 scpcp 很像,基本格式是:

rsync [选项] [源地址] [目标地址]

我们先在本地创建一些测试文件来感受一下。

# 创建两个目录
mkdir dir1 dir2

# 在 dir1 中创建 100 个空文件
touch dir1/file{1..100}

现在,我们想把 dir1 里的所有文件同步到 dir2。最常用的选项是 -a,它代表 “archive”(归档)模式,相当于多个选项的集合(-rlptgoD),可以递归同步并保留文件权限、所有者、时间戳等所有属性。

rsync -a dir1/ dir2

执行后,dir2 就会拥有和 dir1 一模一样的内容。

最重要的细节:尾部的斜杠 /

注意上面命令中 dir1/ 末尾的斜杠。这是 rsync 最容易让人迷惑,也是最关键的一个细节。

  • dir1/ (带斜杠): 表示同步 dir1 目录的内容file1file100 会被直接复制到 dir2 目录下。
  • dir1 (不带斜杠): 表示同步 dir1 这个目录本身。执行后,你会在 dir2 里面看到一个新建的 dir1 目录,文件都在 dir2/dir1/ 下面。

这个小小的斜杠决定了完全不同的目录结构,用错的后果可能很严重。所以,我强烈建议在执行任何 rsync 命令前,都先用 --dry-run(或者缩写 -n)来模拟运行一次。

# 加上 -v (verbose) 可以看到详细的输出
rsync -anv dir1/ dir2

这个命令不会真的执行任何操作,只会打印出它计划要做的所有事情。检查输出,确认符合预期后,再去掉 -n 参数正式执行。血泪教训,请务必养成这个习惯。

远程同步:Push 与 Pull

rsync 的强大之处在于远程同步。只要你的本地机器和远程服务器配置了 SSH 免密登录,rsync 就能无缝工作。

Push:从本地推送到远程

这是最常见的场景,比如部署代码、上传备份。

# 将本地的 dir1 目录(连同目录本身)推送到远程服务器的 /home/user/backups 目录下
rsync -a ~/dir1 user@remote_host:/home/user/backups

# 将本地 dir1 目录的 *内容* 推送到远程
rsync -a ~/dir1/ user@remote_host:/home/user/backups

语法和 scp 非常相似:user@remote_host: 后面跟上远程服务器的路径。

Pull:从远程拉取到本地

反过来,把远程服务器的文件拉到本地也很简单,只需调换源和目标的位置。

# 从远程服务器拉取 /var/log 目录到本地的 ~/server_logs
rsync -a user@remote_host:/var/log ~/server_logs

常用且实用的选项组合

除了 -a-n,下面这几个选项在日常工作中也极其有用。

  • -z (compress): 在传输过程中压缩数据。如果你的网络带宽有限,或者传输的是文本这类容易压缩的文件,这个选项能显著提升速度。
  • -P: 这个选项是 --progress--partial 的结合。--progress 会显示每个文件的传输进度条,而 --partial 则支持断点续传。对于传输大文件或网络不稳定的情况,这哥命令简直是救星。
  • --delete: 一个强大但危险的选项。它会删除目标目录中,源目录不存在的文件。这在做镜像备份(让目标目录和源目录完全一致)时非常有用。但请务必配合 --dry-run 使用,防止误删数据。

所以,一个万金油式的远程同步命令通常是这样的:

# 归档模式、显示进度、压缩、删除多余文件
rsync -azP --delete /path/to/local/source/ user@remote_host:/path/to/remote/destination/

精准控制:排除与包含

有时候我们不想同步所有文件。比如在同步一个项目代码时,我们希望排除 node_modules 目录和所有的 .log 文件。

--exclude 选项可以帮你搞定。

rsync -avz \
  --exclude='node_modules' \
  --exclude='*.log' \
  /path/to/project/ \
  user@remote_host:/path/to/deployment/

--exclude 可以使用多次,也支持通配符。如果排除规则很多,可以把它们写在一个文件里,然后使用 --exclude-from='exclude-rules.txt' 来加载。

--include 的用法稍微复杂些,它通常和 --exclude 配合使用,用来在排除的大规则中"豁免"某些文件。rsync 会按顺序匹配规则,一旦匹配成功就停止。所以 include 规则通常要放在 exclude 规则前面。

自动化你的同步任务:结合 Cron

手动的 rsync 固然好用,但真正的威力在于自动化。我们可以用 cron 来设置定时任务,比如每天凌晨自动备份网站数据。

使用 crontab -e 编辑你的定时任务,添加如下一行:

# 每天凌晨 3:00,将 /var/www/html 目录备份到远程服务器
0 3 * * * /usr/bin/rsync -a --delete /var/www/html/ user@remote_host:/backups/website/

cron 中使用 rsync 有几个关键点:

  1. 绝对路径: cron 的执行环境非常简单,可能找不到 rsync 命令。最好使用绝对路径(用 which rsync 查看)。
  2. SSH 免密登录: 定时任务无法输入密码,所以必须提前配置好 SSH key 认证。
  3. 日志记录: cron 默认会把命令的输出通过邮件发给用户。为了方便排查问题,最好将输出重定向到日志文件,比如: ... > /var/log/rsync_backup.log 2>&1

那些年我们踩过的坑

最后,总结几个我个人和其他人经常遇到的问题:

  1. 尾部斜杠 / 用错: 导致在目标位置创建了多余的目录层级。这是最常见的问题,记住:同步内容用 /,同步目录本身不用。
  2. 权限问题: 同步后发现文件权限不对。多半是忘了用 -a 选项。如果目标目录没有写入权限,rsync 也会失败。
  3. --delete 误删数据: 没有先用 --dry-run 预览,导致目标目录的重要文件被意外删除。
  4. 自动化脚本失败:cron 或脚本里,rsync 找不到命令(没用绝对路径),或者卡在密码输入环节(没配置 SSH 免密)。

总的来说,rsync 是一个值得每个开发者和运维工程师投入时间去掌握的工具。一旦你理解了它最核心的几个概念——增量传输、尾部斜杠、归档模式和干跑测试——你就会发现自己再也回不去那个只会用 scp 的时代了。


关于

关注我获取更多资讯

<img src="/img/gongzhonghao.jpg" alt="公众号" class="wx-contact-img">

<div>📢 公众号</div>
<img src="/img/aixue689.jpg" alt="个人号" class="wx-contact-img">

<div>💬 个人号</div>
使用 Hugo 构建
主题 StackJimmy 设计