rsync 是 Linux/Unix 下非常强大的文件同步工具,它以高效、灵活著称,支持本地和远程同步、增量传输、保留属性等特性。然而,对于初学者(甚至一些老手)来说,源路径末尾是否添加斜杠 / 有着严格且重要 的语义区别。用错了,可能导致文件放错位置,或者在配合 --delete 时意外删除数据。
本文将深入剖析这一细节,并整理 rsync 的常用用法和典型示例,帮助你安全、正确地使用 rsync。
一、核心区别:源路径尾斜杠的有无
假设我们有如下目录结构:
源目录:/home/user/data/
├── file1.txt
└── file2.txt
目标目录:/backup/(当前为空)
1.1 不带尾随斜杠
bash
rsync -av /home/user/data /backup/
语义 :"将整个 data 目录(包括目录本身)同步到目标目录。"
结果:
/backup/
└── data/
├── file1.txt
└── file2.txt
目标路径下多了一层 data 目录。
1.2 带尾随斜杠
bash
rsync -av /home/user/data/ /backup/
语义 :"将 data 目录里的内容(不包括目录本身)同步到目标目录。"
结果:
/backup/
├── file1.txt
└── file2.txt
目标路径下直接是源目录内的文件,没有额外的 data 层级。
二、为什么这个区别很重要?
2.1 与 cp 的习惯不同
在 cp 命令中,cp -r /home/user/data /backup/ 和 cp -r /home/user/data/ /backup/ 行为几乎相同,都是复制整个目录(data 目录本身)。而 rsync 严格区分,容易让习惯 cp 的用户犯错。
2.2 结合 --delete 时的风险
--delete 选项会让 rsync 删除目标目录中源端不存在的文件。这时,加不加斜杠会导致完全不同的删除范围。
示例:
假设目标目录 /backup/ 中有两个文件:
/backup/
├── old.txt
└── data/
└── file1.txt
源目录 /home/user/data/ 中只有 file1.txt。
情况 A:带斜杠
bash
rsync -av --delete /home/user/data/ /backup/
- 比较的是
/backup/的内容与/home/user/data/的内容。 - 由于
old.txt在目标中存在,而源中不存在,它会被删除。 - 结果:
/backup/下只剩下file1.txt。
情况 B:不带斜杠
bash
rsync -av --delete /home/user/data /backup/
- 比较的是
/backup/data的内容与/home/user/data的内容。 old.txt位于/backup/下,不在/backup/data内,因此不会被删除。- 结果:
/backup/old.txt保留,/backup/data/下同步为file1.txt。
由此可见,一个斜杠的差异可能带来完全不同的删除行为。
三、rsync 常用用法与选项
3.1 基本语法
bash
rsync [选项] 源路径 目标路径
- 源路径和目标路径可以是本地路径,也可以是远程路径(格式:
user@host:path)。 - 常用选项:
| 选项 | 说明 |
|---|---|
-a |
归档模式(保留权限、时间戳、属主属组、递归等),相当于 -rlptgoD |
-v |
显示详细信息(verbose) |
-z |
传输时压缩 |
-P |
显示进度并支持断点续传(相当于 --partial --progress) |
--delete |
删除目标目录中源端不存在的文件 |
-n 或 --dry-run |
模拟运行,不实际执行,用于测试 |
-e ssh |
指定使用 SSH 作为远程 shell |
--exclude |
排除指定文件或目录 |
--include |
包含指定文件或目录(与 --exclude 配合使用) |
3.2 常见使用场景
本地同步
bash
# 同步整个目录(保留属性)
rsync -av /source/ /destination/
# 仅同步内容(不带尾斜杠)
rsync -av /source/ /destination
远程同步(推)
bash
# 将本地目录推送到远程服务器
rsync -av -e ssh /local/data/ user@192.168.1.100:/remote/backup/
远程同步(拉)
bash
# 从远程服务器拉取数据到本地
rsync -av -e ssh user@192.168.1.100:/remote/data/ /local/backup/
增量备份并删除多余文件
bash
rsync -av --delete /important/ /backup/important/
模拟运行,查看将执行哪些操作
bash
rsync -av --delete --dry-run /source/ /dest/
排除某些文件或目录
bash
rsync -av --exclude='*.log' --exclude='temp/' /source/ /dest/
四、实用示例集
示例 1:网站代码部署
bash
rsync -avz --delete --exclude='.git' --exclude='node_modules' /local/project/ user@server:/var/www/html/
将本地项目目录内容 同步到远程服务器,删除服务器上多余文件,排除 .git 和 node_modules 目录,并启用压缩。
示例 2:备份家目录(保留权限)
bash
rsync -av /home/user/ /mnt/backup/user-home/
将 /home/user/ 下的所有内容备份到 /mnt/backup/user-home/,注意源路径末尾斜杠确保不会多一层 user 目录。
示例 3:数据迁移(断点续传 + 进度)
bash
rsync -avP /large_data/ /new_disk/data/
使用 -P 显示每个文件的传输进度,并在中断后支持续传。
示例 4:与 SSH 不同端口
bash
rsync -av -e 'ssh -p 2222' /local/ user@remote:/remote/
指定 SSH 端口 2222 进行远程同步。
示例 5:仅同步目录结构(不传文件)
bash
rsync -av -f"+ */" -f"- *" /source/ /dest/
使用 --include 和 --exclude 模式,只复制目录结构,不复制普通文件。
五、总结与最佳实践
-
明确你的意图:
- 如果你想同步目录本身 → 源路径不要加尾斜杠。
- 如果你想同步目录内容 → 源路径加上尾斜杠。
-
在脚本中使用前先
--dry-run:尤其当使用
--delete时,先用-n模拟运行,确认结果符合预期。 -
保持一致性 :
对于目标路径,尾斜杠通常不影响最终结果(但推荐不加,以避免歧义),重点在于源路径。
-
结合
--delete格外小心 :如果不想删除目标中的额外文件,不要使用
--delete;如果使用,务必确认源路径的写法正确。 -
多用
-av组合 :
-a保留了大部分重要属性,-v让你清楚看到同步了哪些文件,是日常使用的最佳搭档。
掌握好源路径尾斜杠的区别,是写出正确、安全 rsync 命令的关键一步。希望本文能帮你避开这个常见的"坑",让 rsync 真正成为你得心应手的文件同步利器。