凡是比”随手复制一个文件”更重的事,都用 rsync;只想着把文件立刻弄到另一台机器上,用 scp。核心区别:scp 每次都把整个文件重新流式传一遍,对断线毫无记忆;rsync 会对比源和目标,只传变化的块,中断的复制从断点接着来。在不稳链路上传大备份,这就是”两分钟搞定”和”从头再来”的差距。两者都随 OpenSSH 附带在几乎每个 Linux 发行版上,所以这是习惯的选择,不是安装的选择——而习惯应该默认 rsync。下文包括:一张直给的对比表、真实的速度差异、scp 做不到的续传技巧,以及 scp 依然是正确答案的场合。
rsync 和 scp 有什么区别?
scp 只做一件事:开一条 SSH 通道,流式传字节,关闭。它在两次运行之间没有任何状态,所以传输在 90% 处断掉,你就从零再来。
rsync 是一个恰好用 SSH 做传输的同步工具。发送之前,它会为目标文件建一份校验和列表(滚动校验和 delta 算法),只传不同的块。同一条命令跑两遍,第二遍几乎不移动任何字节。这也让 rsync 成为保持两个目录同步的天然工具——排个计划任务,每次运行只复制增量。
实际后果:
- 中断:rsync 续传;scp 重传整个文件。
- 第二次复制:rsync 只发变化;scp 全部重发。
- 删除:rsync 能用
--delete镜像删除;scp 不能。 - 过滤:rsync 有
--exclude模式;scp 指哪传哪、全都要。 - 试运行:rsync 用
--dry-run预演;scp 没有对应物。
rsync 比 scp 快吗?
快链路上首次复制单个大文件,两者接近——都在打满 SSH,校验和那一遍只增加一点开销。差距在三个地方拉开:
- 海量小文件。rsync 能流水线化目录遍历并复用一条连接;老式 scp 配置每个文件都要另起一次工作。成千上万的小文件(一个
node_modules、一套 WordPress)用 rsync 明显更快跑完。 - 重复运行。复制一个 4 GB 文件,其中 50 MB 变了:rsync 大约只动 50 MB;scp 重新搬 4 GB。
- 压缩。
-z在传输中压缩,慢速 WAN 链路上有感。
你可以自己计时——两条命令形状相同:
# 同一个文件,同一台服务器,都走 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/ 如果你整天泡在服务器里,传输速度值得量一次——就像繁忙主机上 ss 优于 netstat 一样(见 ss vs netstat:Linux 端口命令怎么选)。
scp 能续传中断的传输吗?
不能。scp 没有续传;1 GB 的文件断在 900 MB,就从头再来。这是每场 rsync-vs-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 什么时候该用 scp 而不是 rsync?
少数几种场合,scp 依然是对的:
- 一个小文件,传一次。敲
scp app.conf user@host:/etc/myapp/比任何 rsync 调用都短,而且没有东西需要续传。 - 对端没有 rsync。rsync 需要两端都有它的二进制。许多最小化容器和设备只带
scp用的 SFTP 服务端,不带 rsync。 - 你不想暴露 rsync 服务。少见,但有些环境专门锁死 rsync daemon。
一个值得知道的细节:OpenSSH 项目多年前就弃用了 scp 的原始协议,现代 scp 底层其实说的是 SFTP。这修掉了一个路径逃逸的怪癖,但丝毫没有改变这里真正要紧的两条局限——不能续传,没有增量传输。换了协议,scp 也不会变成 rsync。
顺带相关:如果你的问题其实是”rsync vs cp”,答案与本文同构——cp 是 scp 的纯本地版(不能续传、没有增量、不加参数连属性都不保留),rsync 则本地远程通吃。本地一次性复制,cp 够用。
哪些 rsync 参数最重要?
大多数人一辈子只需要这一行:
rsync -avh --partial --progress src/ user@server:/srv/dest/ | 参数 | 作用 |
|---|---|
-a(archive) | 递归 + 保留权限、时间、属组、符号链接、设备文件 |
-v(verbose) | 列出正在传输的内容 |
-h(human) | 人类可读的体积 |
--partial | 保留传了一半的文件,重跑即续传 |
--progress | 按文件显示进度——scp 从未有过的东西 |
-z | 传输中压缩(快 LAN 慢 CPU 的组合:别开) |
--delete | 连删除一起镜像——危险,永远先配 dry run |
--dry-run (-n) | 只演不改,展示将会发生什么 |
两个值得养成的习惯。第一,凡带 --delete 先试运行:
rsync -avh --delete --dry-run src/ user@server:/srv/dest/ # 先审查
rsync -avh --delete src/ user@server:/srv/dest/ # 确认后再执行 第二,盯紧末尾的斜杠——/srv/src 会把目录本身复制进目标,/srv/src/ 复制的是目录的内容。这件事每个人都会中招一次;当你想要的是另一种形式时,rsync 甚至会警告 “no bytes transferred”。
每天或每周的同步,把 rsync 放进 systemd timer,让它只复制增量——排程相关的 journalctl 那一半,见 journalctl 速查表。
Rsync 对比 scp:结论
| scp | rsync | |
|---|---|---|
| 随 OpenSSH 附带 | 是 | 是(需要两端都有) |
| 续传中断的传输 | 否 | 是(--partial) |
| 重跑时增量传输 | 否 | 是 |
| 保留权限/符号链接 | 部分 | 完整(-a) |
| 排除模式 | 否 | --exclude |
| 试运行 | 否 | --dry-run |
| 镜像删除 | 否 | --delete |
| 最适合 | 一次性快速复制 | 备份、同步、大型目录树 |
备份、大树、任何经过会断链路的传输、任何会跑不止一次的复制——默认 rsync。命令比念头还短的时候,用 scp。如果只带走一个参数,带走 --partial——它把未来每一次断线,从”从头再来”变成”暂停一下”。
— mrsaynothing
Get the next one by email
One email per post. No spam, no algorithms.
what is this?怎么在本地跑 GGUF 模型:Ollama、llama.cpp 与 vLLM
喜欢这些文章?我的本职工作就是这样的工程。 雇用我