scp、rsync、sftp,什么时候用哪个
一句话总结
这三种工具都运行在 SSH 通道之上。区别在于:是一次发送全部内容(scp)、只发送差异(rsync),还是像对话一样交互传输(sftp)。
为什么需要三种工具
传一个文件却有三种工具,是有原因的。第一次发送一个 100 MB 文件、每天同步一个 10 GB 目录,以及在服务器上查看文件列表后挑选下载,三种场景所需要的特性并不相同。
它们是如何工作的
scp——简单复制
scp -P 2222 -i ~/.ssh/id_ed25519 ./app.tar.gz root@127.0.0.1:/tmp/
scp -r ./dist root@host:/srv/app/
scp -p ./config.yaml root@host:/etc/app/ # mtime/권한 보존
scp root@host:/var/log/app.log ./ # 내려받기
有两点需要注意。
- 端口选项是大写的
-P。 小写的-p表示“保留时间戳”,含义完全不同。偏偏 ssh 使用小写-p指定端口,因此非常容易混淆。 - 新版 OpenSSH 的
scp在内部使用 SFTP 协议。因此,过去可以工作的某些路径扩展行为已经改变,例如由远端 shell 处理 glob。如果需要旧行为,可以通过-O强制使用传统协议。
scp 无法续传。传到 90% 时中断,就只能从头开始,所以它不适合大型传输。
rsync——只发送差异
rsync -aHAX --numeric-ids --delete --dry-run /srv/data/ backup@host:/backup/data/
rsync -avz -e 'ssh -p 2222 -i ~/.ssh/id_labhub' ./dist/ root@127.0.0.1:/srv/app/
必须准确理解各选项的含义。
-a(archive)等同于-rlptgoD,涵盖递归、符号链接、权限、时间、组、所有者与特殊文件。- 有些内容不包含在
-a中。 ACL(-A)、扩展属性(-X)和**硬链接(-H)**必须单独指定。不清楚这一点,恢复后的权限就会出现细微差异。 --numeric-ids使用数字 UID/GID 而不是名称,防止恢复到另一套系统时把所有者错误地映射给其他账户。- 最好养成始终同时使用
-n(--dry-run)和-i(--itemize-changes)的习惯。
还要注意末尾斜杠规则。这是 rsync 最容易出错的地方。
rsync -a /srv/data /backup/ # /backup/data/... 가 만들어진다
rsync -a /srv/data/ /backup/ # /backup/... 에 내용이 바로 들어간다
源路径末尾有斜杠,表示复制“该目录的内容”;没有斜杠,则表示复制“该目录本身”。
--delete 具有破坏性。 如果在源目录为空或挂载已断开的状态下运行,它会删除目标端的全部数据。这是实际工作中经常发生的事故,所以脚本中必须加入防护条件。
set -euo pipefail
[ "$(ls -A "$SRC" | wc -l)" -gt 0 ] || { echo "source empty, abort" >&2; exit 1; }
rsync -aHAX --numeric-ids --delete "$SRC/" "$DST"
可以利用硬链接低成本地制作多代备份。
rsync -aHAX --delete --link-dest=/backup/daily.1 /srv/data/ /backup/daily.0/
--link-dest 不会复制未变更的文件,而是为它们创建指向指定目录中文件的硬链接。每一代看起来都像完整快照,磁盘空间却只用于保存变更部分。
sftp——交互式或批处理
sftp -P 2222 -i ~/.ssh/id_labhub root@127.0.0.1
sftp -b /root/batch.txt -P 2222 root@127.0.0.1
在批处理文件中写入 cd、put、get、ls、mkdir,就能以非交互方式运行。它至今仍广泛用于与合作伙伴自动交换文件。还可以组合 ChrootDirectory 与 ForceCommand internal-sftp,创建没有 shell、只允许传输的专用账户,这也是 sftp 的优势。
实际工作中会遇到的情况
使用不理解硬链接的工具复制多代备份,导致容量膨胀到三倍。 --link-dest 节省下来的空间,会在一次复制中全部消失。-H 不包含在 -a 中,因此必须单独指定。
备份占满带宽,干扰线上服务。 可以组合 --bwlimit=50M 与 ionice -c 3 nice -n 19 来降低优先级。备份不再干扰生产后,反而可以把执行周期缩短。
下一个实验要做什么
连续完成两个实验。首先用 scp 和 sftp 往返传输文件,并通过校验和确认完整性;然后使用 rsync 亲手验证末尾斜杠的差异、制作 --delete 防护,并通过 --link-dest 构建多代备份。