Linux rsync:如何本地和通过 SSH 同步文件
rsync 是一个将文件和目录复制到本地或远程系统并传输更改的工具。默认行为是从源单向复制到目标,目标中仅存在的文件不会被删除,除非指定 --delete。
开始之前
这些示例是在 Linux shell 中运行的。首先,使用 rsync --version 检查是否已安装。在 Ubuntu 上,如果未安装,可以使用以下命令进行安装。对于远程传输,两个系统都需要安装 rsync,并且如果使用 SSH(安全外壳),还需要在目标路径上具有远程访问和写入权限。
sudo apt update
sudo apt install rsync
如果将源路径和目标路径输入颠倒,可能会覆盖或删除您想要的数据。在处理重要数据之前,请确保备份一份单独的副本,尤其是在使用删除选项时,首先使用 --dry-run 检查预期更改。同步不同于恢复到先前状态的备份,因为源中的错误或损坏也可能反映到目标中。
本地目录复制及斜杠的区别
下面是一个在主目录下创建新练习文件夹并准备一个文件的示例。如果存在同名文件夹,请使用不同的名字。
mkdir -p "$HOME/rsync-demo/source" "$HOME/rsync-demo/dest"
printf 'hello\n' > "$HOME/rsync-demo/source/hello.txt"
rsync -av "$HOME/rsync-demo/source/" "$HOME/rsync-demo/dest/"
ls -l "$HOME/rsync-demo/dest/"
如果上一个命令的结果中出现了 hello.txt,说明源目录的内容已复制到目标目录。再次运行相同的 rsync 命令通常不会重新传输未更改的普通文件。基本比较使用文件大小和修改时间,因此不能完全验证内容是否相同。
源末尾的 / 表示目录中的内容(而不是目录本身)被复制到目标。如果目标目录已存在且省略斜杠,则源目录名称将被创建在目标下。
rsync -av "$HOME/rsync-demo/source" "$HOME/rsync-demo/dest/"
运行此命令将创建 dest/source/hello.txt。之前创建的 dest/hello.txt 将保持不变。这两个路径之间的差异在使用删除选项时尤其重要。如果路径中有空格,请像示例中一样用引号括起来。
常用选项和预检查
-a:这是归档模式。它要求递归复制并保留时间、权限、所有者、组和符号链接。所有权的保留可能会根据权限和目标文件系统的支持而受到限制。ACL 和扩展属性不包含在-a中。-v:显示详细的操作输出。-n或--dry-run:显示预期的操作而不实际进行任何更改。-z:在传输过程中使用压缩。其效果取决于网络状况和文件类型,对于本地复制并非总是必要。
例如,在实际复制之前,你可以按如下方式进行检查。输出显示预期的变化,如果在试运行和实际执行之间文件发生变化或出现错误,实际结果可能会有所不同。
rsync -avn "$HOME/rsync-demo/source/" "$HOME/rsync-demo/dest/"
如果你需要检查大小和修改时间相同的文件是否实际上内容不同,你可以考虑--checksum比较,但由于需要读取两个文件,这可能会很耗费资源。有关选项的详细含义,请参考rsync 官方手册。
删除仅存在于目标位置的文件
--delete 会删除同步目标目录中源中不存在的项目。如果您不小心指定了错误的目标或目录级别,必要的文件也可能被删除,因此请先检查目标路径和源路径的尾部斜杠,并查看试运行的结果。
以下示例可以列出仅存在于目标中的项目,就像上面创建的 dest/source/ 一样,以便删除。仅在练习文件夹中没有需要保留的文件时运行。
rsync -avn --delete "$HOME/rsync-demo/source/" "$HOME/rsync-demo/dest/"
检查输出中的 deleting 条目,只有在删除范围正确并且备份可用于恢复的情况下才删除 -n 并进行实际执行。
rsync -av --delete "$HOME/rsync-demo/source/" "$HOME/rsync-demo/dest/"
此命令仅更改目标,不会从源删除文件。仅存在于目标中的文件可能无法恢复,除非使用常规文件恢复程序。请为操作数据准备单独的版本备份和恢复验证。
排除文件或目录
要从传输目标中排除源中的 cache 目录,请按如下方式指定。由于源内容是传输根,因此前导斜杠指的是该根下的 cache。首先运行试验,以确保仅排除所需项目。
rsync -avn --exclude='/cache/' "$HOME/rsync-demo/source/" "$HOME/rsync-demo/dest/"
如果结果正确,删除 -n 并复制它。默认的排除规则通常会保护 --delete 中目标的排除项,但使用 --delete-excluded 或更改过滤规则可能会改变行为。在将复杂模式应用到实际数据之前,请在单独的文件夹中进行检查。
通过 SSH 与远程服务器同步
在准备好 SSH 访问的环境中,以下命令将本地源的内容发送到远程服务器上的目标目录。将 user、server.example.com 以及路径替换为实际值,并事先准备好远程目标目录。第一次连接时,请通过可信渠道验证服务器的主机密钥指纹。
rsync -avn -e ssh "$HOME/rsync-demo/source/" user@server.example.com:/home/user/backup/
在查看预期的传输列表后,移除 -n 以进行传输。相反,要从远程服务器检索到本地机器,请将远程路径设置为源位置。
rsync -avn -e ssh user@server.example.com:/home/user/backup/ "$HOME/rsync-demo/dest/"
如果 SSH 端口与默认端口不同,例如,使用 -e 'ssh -p 2222'。对于远程访问,建议使用具有有限权限的账户和 SSH 密钥认证。不要在命令中直接输入密码,因为它可能会在进程信息或 shell 历史中被泄露;因此,不使用上一篇文章中的 sshpass -p 示例。在自动化任务中,应同时管理密钥保护和访问范围。




