rsync (remote sync) 是一款功能强大的文件同步和传输工具,广泛应用于 Linux/Unix 系统中。它以其高效的增量同步算法而闻名,该算法只传输源文件和目标文件中存在差异的部分,从而大大减少了网络带宽的消耗和数据传输时间。
这对于备份、镜像和服务器之间的数据迁移等场景至关重要。
rsync 的核心优势
- 增量同步:只传输文件的差异部分,速度极快。
- 保持属性:可以保持文件的权限、时间戳、所有者和组信息。
- 安全传输:可以配合 SSH,使用加密通道进行安全的数据传输。
- 功能丰富:支持排除、包含特定文件/目录,支持删除目标端多余文件等。
基本语法
rsync 的基本命令格式如下:
Bash
rsync [options] SRC... [DEST]
[options]: 选项,例如-a,-v,-z等。SRC: 源目录或文件。DEST: 目标目录或文件。
SRC 和 DEST 可以是本地路径,也可以是远程路径。远程路径的格式为 [user@]host:path。
最常用和最重要的选项组合 -avz
在绝大多数场景下,我们都会使用 -avz 这个组合,它非常实用且高效。
Bash
rsync -avz [SRC] [DEST]
-a, --archive:归档模式,表示以递归方式传输文件,并保持所有文件属性。它等同于-rlptgoD的组合。-r:递归复制目录。-l:复制符号链接本身,而不是链接所指向的文件。-p:保持文件权限。-t:保持文件修改时间。-g:保持文件所属组。-o:保持文件所有者(仅 root 用户有效)。-D:保持设备文件和特殊文件。
-v, --verbose:详细模式,显示同步过程中的详细信息。建议在手动执行时开启,方便观察过程。-z, --compress:在传输过程中压缩数据,可以有效减少网络带宽占用,但会增加一点 CPU 负担。
实用场景与命令示例
1. 本地目录同步
将 /path/to/source/ 目录下的所有内容同步到 /path/to/destination/。
重要提示: 源路径 SRC末尾的 / 非常关键。
source/(带斜杠):表示将source目录 内 的所有文件和子目录复制到目标目录。source(不带斜杠):表示将source目录 本身 连同其内容一起复制到目标目录。
示例 A:复制源目录内的内容
Bash
# 操作前请务必确认路径,避免数据覆盖! # 此命令会将 /home/user/data/ 目录下的 file1.txt, subdir/ 等内容 # 同步到 /mnt/backup/ 目录下 # 最终结果是 /mnt/backup/file1.txt, /mnt/backup/subdir/ rsync -avz /home/user/data/ /mnt/backup/
示例 B:复制源目录本身
Bash
# 操作前请务必确认路径,避免数据覆盖! # 此命令会将 /home/user/data/ 目录本身同步到 /mnt/backup/ # 最终结果是 /mnt/backup/data/file1.txt, /mnt/backup/data/subdir/ rsync -avz /home/user/data /mnt/backup/
2. 通过 SSH 从本地同步到远程服务器
这是最常见的服务器运维场景之一,例如将本地开发好的网站文件推送到服务器。
Bash
# 务必确认目标路径和权限! # 将本地 /var/www/my-project/ 目录下的所有文件 # 同步到远程服务器 192.168.1.100 的 /var/www/html/ 目录下 # 使用 root 用户身份登录远程服务器 rsync -avz /var/www/my-project/ [email protected]:/var/www/html/
如果你的远程服务器 SSH 端口不是默认的 22,可以使用 -e 选项指定端口:
Bash
# 假设 SSH 端口为 2222 rsync -avz -e "ssh -p 2222" /var/www/my-project/ [email protected]:/var/www/html/
3. 从远程服务器同步到本地
这个场景常用于备份服务器数据到本地。
Bash
# 务必确认本地备份路径! # 将远程服务器 192.168.1.100 的 /var/log/ 目录 # 完整同步到本地的 /home/user/server_logs/ 目录下 rsync -avz [email protected]:/var/log /home/user/server_logs/
高级用法与常用选项
4. --delete:删除目标目录中多余的文件
默认情况下,rsync 只会进行增量添加和修改。如果你希望目标目录和源目录保持 完全一致(即源目录中已删除的文件,在目标目录中也一并删除),就需要使用 --delete 选项。
⚠️ 警告:--delete 是一个危险的选项! 使用前请务必再三确认你的源路径和目标路径是否正确,否则可能导致目标目录文件被意外删除。强烈建议先使用 --dry-run 选项进行测试。
Bash
# 将 /home/user/docs/ 的内容完整镜像到 /mnt/backup/docs/ # 如果 /mnt/backup/docs/ 中有而 /home/user/docs/ 中没有的文件,将会被删除 rsync -avz --delete /home/user/docs/ /mnt/backup/docs/
5. --dry-run:演习模式,不实际执行
这是 rsync 一个极其有用的安全功能。使用 -n 或 --dry-run 选项,rsync 会模拟整个同步过程,并列出它 计划 要做的所有文件操作(复制、更新、删除),但不会真正执行任何操作。
在使用 --delete 或执行重要的同步任务前,先用 --dry-run 跑一遍是绝佳的安全习惯。
Bash
# 模拟执行一次带删除的同步,看看会发生什么 rsync -avzn --delete /home/user/docs/ /mnt/backup/docs/
6. --exclude 和 --include:排除或包含文件/目录
当你只想同步特定文件或排除某些临时文件、日志文件时,这两个选项非常有用。
--exclude=PATTERN:排除匹配PATTERN模式的文件或目录。--include=PATTERN:包含匹配PATTERN模式的文件或目录(通常与--exclude结合使用)。
示例 A:排除单个目录和所有 .log 文件
Bash
# 同步 /var/www/my-project/,但排除 node_modules 目录和所有的 .log 文件 rsync -avz --exclude 'node_modules/' --exclude '*.log' /var/www/my-project/ user@remote:/deploy/
示例 B:使用 --exclude-from 从文件中读取排除列表
如果排除规则很多,可以把它们写在一个文件里,每行一个规则。
exclude-list.txt 文件内容:
node_modules/ .git/ *.log tmp/
然后执行命令:
Bash
rsync -avz --exclude-from='exclude-list.txt' /var/www/my-project/ user@remote:/deploy/
7. --progress:显示传输进度
当传输大文件时,这个选项非常人性化,它会显示每个文件的传输进度条。
Bash
# 传输大文件时显示进度 rsync -avz --progress large-video-file.mp4 user@remote:/media/
如果你希望看到总的进度,可以使用 --info=progress2。
Bash
# 显示总的传输进度,而不是单个文件的 rsync -avz --info=progress2 /path/to/source/ user@remote:/path/to/dest/
总结
- 始终明确源路径末尾的
/:它决定了是复制目录内容还是目录本身。 - 默认使用
-avz:这个组合能满足 90% 以上的需求。 - 使用
--delete前,必用--dry-run测试:这是防止数据丢失的黄金法则。 - 利用
--exclude:在同步项目代码或备份时,排除版本控制目录 (.git,.svn)、依赖目录 (node_modules) 和临时文件,可以大大提高效率和整洁性。 - 配合
cron定时任务:将rsync命令写入脚本,并添加到crontab中,可以轻松实现自动化、无人值守的定时备份。