使用 rsync 传输数据到开发机
在向智算云平台的主机传输数据时,scp / sftp 是常用的命令行工具。但是如果对断点续传有比较高的要求,rsync 可能是更好的选择。
一个典型场景是文件夹包含大量小文件和几个大文件,并且网络带宽有限,那么 rsync 的增量传输和断点续传功能能够有效地减少带宽使用和传输时间。
Windows、macOS 和 Linux 对 rsync 的支持
- Linux 通常可以通过系统软件源安装 rsync,但预装情况和版本取决于发行版与镜像。
- macOS 可能预装 rsync 或兼容实现,但系统程序可能只兼容旧版 rsync 2.6.x。命令存在不代表它支持本文使用的所有选项。
- Windows 默认不支持 rsync,需要使用 WSL 或 Cygwin。
- 如果开发机使用的镜像中未提供 rsync,也需要使用 Linux 包管理器自行安装。
新手提示
Windows 端操作难度较高,如果不熟悉 Windows 开发,建议选择其他数据传输方式。
准备工作
本地安装 rsync
首先,检查本地实际调用的 rsync 程序和软件版本:
command -v rsync
rsync --version本文的命令使用 --inc-recursive 和 --info=progress2。--inc-recursive 只有在两端均为 rsync 3.0.0 或更高版本时才能使用增量递归算法,--info=progress2 要求发起传输的一端为 rsync 3.1.0 或更高版本。为获得一致行为,本文要求本地和远程主机都使用 rsync 3.1.0 或更高版本。3.1.0 是兼容性最低要求,应优先使用系统软件源提供的当前维护版本。
macOS 用户可以通过 Homebrew 安装新版,并单独确认 Homebrew 程序的版本:
brew install rsync
"$(brew --prefix)/bin/rsync" --version
command -v rsync
rsync --version重要
安装完成后,当前 Shell 仍可能调用 /usr/bin/rsync。如果 command -v rsync 没有显示 Homebrew 路径,请按照 Homebrew 提示调整 PATH,或在传输命令中使用 "$(brew --prefix)/bin/rsync"。查看完整版本输出中的 rsync 软件版本,不要只根据 protocol version 判断兼容性。
确认远程主机上的 rsync
本文使用 rsync 传输数据到开发机,因此远程主机指开发机。
请在开发机上执行以下命令,检查实际程序和版本:
command -v rsync
rsync --version如果没有,可以使用以下命令安装和更新(以 Ubuntu 为例):
sudo apt-get update
sudo apt-get install rsync两端版本号不必完全相同,但都应满足 rsync 3.1.0 或更高版本的最低要求。
了解 zsh、bash 和文件系统差异
本文的命令使用 zsh 和 bash 均支持的 POSIX 风格引号与换行语法。从 macOS zsh 向 Linux bash 环境传输时,不需要仅因为 Shell 不同而改写命令;rsync 按字节传输文件,不会转换文件内容或换行符。需要注意以下差异:
- 路径包含空格、方括号或通配符时,应引用完整参数。尤其不要在 zsh 中使用未引用且无法匹配的通配符,因为 zsh 和 bash 的默认处理不同。
-a会请求保留权限、时间、符号链接、所有者和组,最终结果取决于两端账户和权限。如果不需要保留 macOS 的所有者和组,可在-a后添加--no-owner --no-group,并在传输后检查 Linux 目标权限。-a不包含 ACL 和扩展属性。只有两端文件系统均支持且业务依赖这些元数据时,才添加-A或-X并先做小范围验证。- macOS 文件系统通常不区分文件名大小写,并可能使用与 Linux 不同的 Unicode 文件名规范化方式。包含仅大小写或规范化形式不同的文件名时,应先验证代表性目录。
-a保留符号链接本身。指向/Users/...等 macOS 绝对路径的链接在 Linux 中通常不可用。
生成示例数据文件
我们可以使用 dd 命令生成一个用于测试 rsync 数据传输的大文件:
dd if=/dev/urandom of=dummyfile bs=1M count=150这会创建一个 150MB 的随机数据文件,用于演示 rsync 的功能。
获取开发机 SSH 连接信息
请登录智算云平台,查看开发机的 SSH 连接命令。
SSH 连接命令示例:-p 38526 root@8.140.242.203
其中包含当前开发机的 SSH 端口号、用户名、SSH 主机 IP,下一步中将会使用。root 为默认 SSH 登录用户名(部分旧版实例展示为非 root 普通用户名,请重启)。
使用 rsync 传输数据
继续操作前,请完成准备工作中的本地和远程版本检查,确认两端均使用 rsync 3.1.0 或更高版本。
包含 SSH 端口号的 rsync 命令
智算云平台的开发机使用非默认 SSH 端口,我们需要在 rsync 命令中指定端口。
使用 -e 选项来设置 SSH 参数后,rsync 命令结构变为如下格式:
rsync -e "ssh -p PORT" [其他选项] 源目录 用户名@远程主机:目标目录传输单个文件
要传输单个文件到远程主机,使用以下命令:
rsync -a \
--partial \
--partial-dir=.rsync-partial \
--info=progress2 \
--human-readable \
-e "ssh -T -o Compression=no -p PORT" \
/path/to/local/file \
username@remote_host:/path/to/destination/-a: 归档模式,保留文件属性--partial: 保留未完成文件--info=progress2: 显示总体进度--partial-dir=.rsync-partial: 将部分传输的文件保存在指定目录Compression=no: 避免对模型、压缩包和图片等通常已压缩的数据重复压缩
例如,要将生成的测试文件传输到远程主机的 /root/ 目录:
rsync -a --partial --partial-dir=.rsync-partial --info=progress2 --human-readable \
-e "ssh -T -o Compression=no -p 33260" \
dummyfile root@8.140.242.203:/root/如果目标位置已有该文件,rsync 会比较文件差异,只传输不同部分。
传输整个目录
要传输整个目录及其内容,使用以下命令:
rsync -a \
--inc-recursive \
--partial \
--partial-dir=.rsync-partial \
--info=progress2 \
--human-readable \
-e "ssh -T -o Compression=no -p PORT" \
/path/to/local/directory \
username@remote_host:/path/to/destination/注意源目录路径末尾没有斜杠 /。如果加上 /,表示要传输目录的内容而不是目录本身。
例如,要将 ~/Desktop/very-important-folder 同步到远程主机的 /root/very-important-folder,可以使用以下命令:
rsync -a --inc-recursive --partial --partial-dir=.rsync-partial --info=progress2 --human-readable \
-e "ssh -T -o Compression=no -p 33260" \
~/Desktop/very-important-folder root@8.140.242.203:/root/very-important-folder/传输完成后远端的文件结构:
(base) root@is-c7wqsja2wznj73pe-devmachine-0:~$ tree -L 2
.
└── very-important-folder
├── ssh.jpeg
├── ssh-port-forwarding-copilot.png
├── ssh-port-forwarding-http.jpeg
└── ssh-port-forwarding-via-aicoder.png
1 directory, 4 files使用 --exclude 选项排除特定文件或目录
如果想排除某些文件或目录,可以使用 --exclude 选项:
rsync -a --inc-recursive --partial --partial-dir=.rsync-partial \
--info=progress2 --human-readable --exclude='*.txt' \
-e "ssh -T -o Compression=no -p PORT" \
/path/to/local/directory/ username@remote_host:/path/to/destination/这个命令会排除所有 .txt 文件。
使用 --delete 选项同步目录
如果想让目标目录与源目录完全一致(删除目标目录中源目录没有的文件),可以使用 --delete 选项:
rsync -a --inc-recursive --partial --partial-dir=.rsync-partial \
--info=progress2 --human-readable --delete --dry-run \
-e "ssh -T -o Compression=no -p PORT" \
/path/to/local/directory/ username@remote_host:/path/to/destination/请谨慎使用此选项,因为移除 --dry-run 后,它会删除目标目录中的文件。先检查演练输出并确认方向和路径无误,再执行实际删除。
模型、压缩包和图片通常已经压缩,默认不要添加 -z。只有源数据以可压缩文本为主且带宽确实成为瓶颈时,才在小范围测试压缩效果。
传输大量数据时先只运行一个 rsync 进程。单个文件可以大于客户端或服务端内存;内存压力主要来自文件条目数量、并发进程和需要全局跟踪文件关系的选项。包含数百万个文件时,按一级子目录分批串行传输,并避免使用 -H。
总结
以上就是使用 rsync 从本地传输数据到远程 Linux 主机的基本步骤。rsync 是一个强大的工具,有很多高级选项可以根据具体需求进行调整。在使用 --delete 等可能造成数据丢失的选项时,建议先使用 --dry-run 选项进行测试,以确保操作的正确性。
常见问题解答
如何进行断点续传?
rsync 可以复用保留的未完成文件。要让中断后的传输具备可恢复性,请在首次传输时使用以下选项,并在中断后重新运行同一条命令:
--partial:保留未完成文件,而不是在中断后删除。--partial-dir=.rsync-partial:将未完成文件保存在目标目录下的指定子目录中。--info=progress2:显示总体传输进度,不为每个文件生成详细日志。
使用这些选项的命令示例:
rsync -a --inc-recursive --partial --partial-dir=.rsync-partial \
--info=progress2 --human-readable \
-e "ssh -T -o Compression=no -p PORT" \
/path/to/local/directory/ username@remote_host:/path/to/destination/如果传输中断,只需再次运行此命令,rsync 会从中断处继续传输。
注意
即使启用了以上选项,rsync 在部分文件缺失、源文件已变化或两端版本不兼容时仍可能重新传输。两端版本号不必完全相同,但都应满足本文的最低版本要求,并且在整个传输过程中不要改动源文件。
scp 是否也具有断点续传的功能?
不,scp(Secure Copy)并不具有与 rsync 相同的断点续传功能。如果使用 scp 传输文件时连接中断,再次运行相同的命令不会从中断处继续传输,而是会重新开始整个文件的传输。
scp 的主要优点是简单易用,但在处理大文件或不稳定网络环境时,rsync 通常是更好的选择。rsync 不仅支持断点续传,还能够只传输文件的变化部分,这使得它在同步和备份任务中特别有效。
如果你经常需要处理大文件传输或在不稳定的网络环境中工作,建议使用 rsync 而不是 scp。但对于简单的、小型的文件传输任务,scp 仍然是一个有用且直观的工具。