rsync 多个 {src,dest} 对

rsync 多个 {src,dest} 对

我有一个正在部署代码的远程服务器。我目前正在使用scp上传代码,但scp速度非常慢,我想切换到rsync(或其他更有效的东西)。瓶颈在于建立ssh连接,因此我想尽量减少与服务器建立的连接数量。

在本地,我的构建过程输出一个out包含bin,libetc子目录的目录。我将输出文件的子集推送到远程服务器上的匹配位置。

我的scp命令如下所示:

scp out/bin/$BINFILES remote:/usr/bin
scp out/lib/$LIBFILES remote:/usr/lib
scp out/etc/$ETCFILES remote:/etc

这将建立与远程服务器的三个连接,并完整复制文件,即使它们没有被修改。这就是我所做的rsync

rsync -e ssh -avz out/bin/$BINFILES remote:/usr/bin
rsync -e ssh -avz out/lib/$LIBFILES remote:/usr/lib
rsync -e ssh -avz out/etc/$ETCFILES remote:/etc

它更快(压缩和消除重复项),但仍然与远程服务器建立三个连接。

有没有办法使用单个rsync命令来实现这三个副本?如果可行的话,我愿意在复制之前将所有 {src,dest} 对放入临时文件中。

我也愿意尝试不同的工具,但它应该适用于 OS X(我当前的开发平台),并且它最好应该支持传输优化rsync

答案1

多个连续的 rsync 命令速度慢的原因是建立 SSH 连接需要一些时间。您可以通过以下方式解决这个问题使用已建立的 SSH 通道设置主连接共享,然后打开一个主连接,不加更改地使用 rsync 命令(请注意,这-e ssh是十年左右以来的默认命令),最后关闭 SSH 连接:

ssh -Nf remote
rsync -avz out/bin/$BINFILES remote:/usr/bin
rsync -avz out/lib/$LIBFILES remote:/usr/lib
rsync -avz out/etc/$ETCFILES remote:/etc
ssh -O exit remote

如果您无法使用 SSH 连接共享(例如,因为一侧正在运行 Dropbear 或非常旧版本的 OpenSSH),您可以建立隧道,但是这样比较麻烦。

或者,通过一些工作,您可以将 rsync 命令重构为一个,方法是使用rsync过滤器和符号链接。如果您可以移动binlib目录,那就很容易了:

mkdir out/usr
mv out/bin out/lib out/usr/
rsync -avz \
      --include='/bin/***' --include='/lib/***' --include='/etc/***' \
      --exclude='*' out/ remote:/

如果您无法移动它们,但您正在复制的树中没有任何绝对符号链接,则可以使用绝对符号链接并告诉 rsync 将其视为目录:

ln -s "$PWD" out/usr
rsync -avz --copy-unsafe-links \
      --include='/bin/***' --include='/lib/***' --include='/etc/***' \
      --exclude='*' out/ remote:/

相关内容