我创建了一个程序,它遍历一堆文件并调用其中一些文件:
scpuser@host:
但是,在我的情况下,可能有数千个需要传输的小文件,并且scp正在为每个文件打开一个新的ssh连接,这有很多开销.
我想知道是否没有解决方案,我保持一个进程运行,维护连接,我可以发送它"请求"复制单个文件.
理想情况下,我正在寻找一些发送器和接收器程序的组合,这样我就可以在开始时启动一个进程(1):
ssh user@host receiverprogram
对于每个文件,我调用一个命令(2):
senderprogram
并将(2)的输出传递给(1)的输入,这将导致文件被传输.最后,我可以发送进程(1)一些信号终止.
优选地,发送器和接收器程序是用于Unix的开源C程序.他们可以使用套接字而不是管道或任何其他创造性解决方案进行通信.
但是,在迭代它时,每个文件都被传输是一个重要的约束:收集文件列表然后调用一个实例scp
在结束时一次传输所有文件是不可接受的.此外,我只有简单的shell访问接收主机.
更新:我找到了使用ssh的多路复用功能解决连接开销问题的解决方案,请参阅下面的答案.然而,我正在开始赏金,因为我很想知道是否存在我在这里描述的发送者/接收者程序.似乎应该存在可以使用的东西,例如xmodem/ymodem/zmodem?
我从另一个角度找到了解决方案.从版本3.9开始,OpenSSH支持会话多路复用:单个连接可以承载多个登录或文件传输会话.这避免了每个连接的设置成本.
对于问题的情况,我可以首先打开一个连接,在特定位置设置一个-M
带有socket(-S
)的控件master().我不需要会话(-N
).
ssh user@host -M -S /tmp/%r@%h:%p -N
接下来,我可以调用scp
每个文件并指示它使用相同的套接字:
scp -o 'ControlPath /tmp/%r@%h:%p'user@host:
此命令几乎立即开始复制!
您还可以使用控制套接字进行正常的ssh连接,然后立即打开:
ssh user@host -S /tmp/%r@%h:%p
如果控制套接字不再可用(例如,因为您杀死了主控),则会回退到正常连接.本文提供了更多信息.