rsync 对 scp——Linux 复制命令怎么选
rsync 记得,scp 忘了:一行命令逐旗标注解、--partial --append-verify 续传咒语、重跑时的差量传输,以及那张裁决表——每条命令都能原样运行。
Both ship with OpenSSH on virtually every Linux distribution — this is a 习惯的选择,不是安装的选择,这个习惯应该默认是 rsync。差别在状态:scp 打开 SSH 通道、流式传字节、关闭,什么都不记得。rsync 发送前先对目标建一份校验和清单,只搬有差异的部分。本页的一切都从这句话推出来。
rsync 用于备份、大目录树、任何你会跑不止一次的事——scp 用于一次性传一个小文件。
scp 不能续传:1 GB 传到 900 MB 掉线——差 100 MB——从零重来。rsync 加 --partial --append-verify 能把这次重启变成一次暂停。
On re-runs rsync moves 只有变更的块; scp re-sends everything. The one flag to take away: --partial.
一行命令,逐旗标注解
大多数人只需要这一条——每个旗标都标了说明,按顺序:
结尾斜杠人人都会踩一次——rsync 甚至会警告 "no bytes transferred",而你本意是另一种写法
状态差异买到了什么
scp does one thing: open an SSH channel, stream the bytes, close. No state between runs, so a transfer that dies at 90% restarts from zero and re-sends the whole 1,000 MB. rsync 是一个恰好用 SSH 做传输的同步工具:发送前先对目标建滚动校验和清单(rolling-checksum
- 中断:rsync 续传;scp 重传文件。
- 第二次拷贝:rsync 只发变化;scp 全部重发。
- 删除:rsync 能用
--delete镜像删除;scp 做不到。 - 过滤:rsync 有
--exclude模式;scp 你指什么拷什么。 - 试运行: rsync shows what it would do with
--dry-run;scp 什么都没有。
rsync 更快吗?
首次通过快速链路拷一个大文件,两者接近——都会吃满 SSH,校验那一遍只添一点小开销。差距在三处打开:
- 海量小文件。 rsync 能流水线化目录遍历并复用连接;老版 scp 每个文件起一个进程。成千上万的小文件——一个
node_modules、一套 WordPress——用 rsync 收尾明显更快。 - 重跑。 拷一个 4.0 GB 文件、其中变了 50 MB,rsync 大约搬 50 MB;scp 再搬 4 GB。
- Compression.
-z在飞行中压缩,慢速广域网上有帮助。
你可以自己掐表——命令形状相同,答案藏在重跑里:
# 同一文件、同一服务器,都走 SSH
time scp bigfile.tar.gz user@server:/tmp/
time rsync -avh --progress bigfile.tar.gz user@server:/tmp/
# 两个都重跑:scp 重拷,rsync 校验后几乎不发东西
time scp bigfile.tar.gz user@server:/tmp/
time rsync -avh --progress bigfile.tar.gz user@server:/tmp/
续传咒语
不,scp 无法续传中断的传输——没有旗标,没有窍门。rsync 的整个设计就假定传输有时会断:
rsync -avh --partial --append-verify --progress bigfile.tar.gz user@server:/srv/backup/
--partial保留写到一半的文件而不是删掉它。--append-verify以追加方式续传,然后校验追加区域——比老的纯--append. 更能防住损坏的半个文件。--progress显示它从哪儿接上。
包进重试循环里,这就是一条即使链路恶劣也能“设好就忘”的备份:
until rsync -avh --partial --append-verify --progress \\
./bigfile.tar.gz user@server:/srv/backup/; do
sleep 5
done
验证:再跑一次同一个 rsync → 它校验后几乎什么都不发
scp 什么时候还赢
- 一个小文件,就一次。 敲
scp app.conf user@host:/etc/myapp/比任何 rsync 调用都短,而且没有东西需要续传。 - 对端没有 rsync。 rsync 需要两端都有它的二进制。许多极简容器和设备只带 scp 的 SFTP 服务器,不带 rsync。
- 你不想暴露 rsync 守护进程。 少见,但有些环境专门锁死 rsync 守护进程。
One subtlety worth knowing: the OpenSSH project deprecated scp's original protocol years ago, and modern scp actually speaks SFTP 在底层。这修掉了一个路径转义的怪癖,但对要紧的两个局限毫发无损——不能续传,没有差量传输。换了协议不等于 scp 变成了 rsync。如果你的问题其实是“rsync 对 cp”:cp 是只在本地的 scp 等价物——不续传、无差量、不加旗标就不保留属性——本地一次性拷贝用它没问题。
危险的那一个
--delete 连删除也镜像——把目标处源里已消失的文件删掉。做镜像强大,其他场合危险。先试运行:
rsync -avh --delete --dry-run src/ user@server:/srv/dest/ # 先审阅
rsync -avh --delete src/ user@server:/srv/dest/ # 再执行
验证:--dry-run 那一遍会打印删除清单且不改动任何东西
每日或每周同步,把 rsync 塞进 systemd timer,只让它拷差量——运行留下的故事都在日志库里。
裁决表
| scp | rsync | |
|---|---|---|
| 随 OpenSSH 附带 | Yes | 是 |
| 续传中断的传输 | No | 是(--partial) |
| 重跑时的差量传输 | No | Yes |
| 保留权限/符号链接 | 部分 | 完整(-a) |
| 排除模式 | No | --exclude |
| 试运行 | No | --dry-run |
| 镜像删除 | No | --delete |
| 最适合 | 快速一次性拷贝 | 备份、同步、大目录树 |
备份、大目录树、任何经过可能掉线链路的东西、任何你会跑不止一次的东西,默认 rsync。命令是一次性的、且不会中断时用 scp——并且永远加上 --partial——它把未来每一次掉线从重启变成暂停。
拷贝页到此为止 · 未取一分毫 · 一切皆本地