将 ssh 和 scp 合并在一个 ssh 会话中

将 ssh 和 scp 合并在一个 ssh 会话中

我有一个如下所示的脚本:

ssh host command1
scp file1 host:/tmp
ssh host command2

有没有一种方法可以将它们全部合并到一个ssh/scp调用中?我遇到的问题是将复制文件与执行命令结合起来,这必须交错完成。本来希望有这样的事情:

ssh_sometool host -c command1 -cp file1 /tmp -c command2

这与语法无关(我可以编写这样的函数),而是与同一ssh会话中发生的所有事情有关

答案1

首先,没有直接或标准的方法可以做你想做的事。另外,让我澄清一下:没有办法用默认的 ssh 客户端做你想做的事

有一个非常古老的叉子ssh-xfer。请注意,即使该工具的开发人员也强调他们的解决方案是“hackish”并且非常旧,因此您不应该使用它。为与此工具一起使用而修补的最新 SSH 版本是OpenSSH-3.8.1p1(在 Arch Linux 上,当前版本是OpenSSH_7.6p1)。

如果让事情快速减少主机之间的连接/握手数量对您来说很重要,您可能会考虑某种配置/编排工具。安西布尔似乎是完成任务的最简单方法,无需太多额外的配置可能是最快的。

无论如何,Ansible 和 Salt 都利用额外的连接来使事情正常工作,我不确定使用它们而不是 ssh/scp 组合是否会赢得一些性能方面的好处。

更新:如果您必须推送和拉取大量文件,并在这些传输之间运行一些附加脚本,则几乎所有配置工具(Chef、Puppet、Salt、Ansible)都会比普通 ssh/scp 更快地完成该操作。

答案2

SSH 允许会话在断开连接后仍保持一段时间,因此您下次无需启动连接。以下是 ssh 配置启用它的选项:

Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 30

ControlMaster允许通过单个网络连接共享多个会话。当设置为 时auto,每次新尝试都会检查相应的连接是否存在并使用它或创建新连接。

ControlPath指定存储连接的路径。确保该路径存在!即创建目录(插座在这里,但可以根据需要手动命名)。

ControlPersist指定断开连接后连接的持续时间。它接受以秒为单位的时间。

要进一步说明选项,请使用man ssh_config.

将这些添加到您的 后~/.ssh/config,将为这三个命令仅打开一个会话。

在我的计算机上,它提供了 5 倍的加速:与某些(附近)主机的 100 个连续连接在 30 秒内工作,没有持久会话,而与它们的连接只需要 5-6 秒。

PS 有时(例如,如果您更改了网络)现有的 ssh 连接会中断,并且新的连接不会建立,因为带有连接的文件确实存在。在这种情况下,只需手动~/.ssh/sockets删除必要的文件即可。

答案3

您可以通过 ssh 标准输入加入并传递所有文件,并在远程会话中接收它们,我的意思是这样的:

tar -cf - file1 file2 | ssh host 'TDIR=`mktemp -d`; tar -xf - -C "$TDIR"; cat "$TDIR/file1"; command1; command2 ...'


  • cat "$TDIR/file1"命令只是如何访问收到的文件的示例;
  • 在本地和远程端使用 tar 和 -j 或 -J 开关来传递压缩文件;
  • 您可以将所有命令放入 bash 脚本中,将其包含在存档中并在远程端执行,例如...tar -xf - -C "$TDIR"; bash "$TDIR/script.sh"'

答案4

在您的脚本中,一旦第一行运行......

ssh host command1

执行将交给 ssh + 您的第二个命令 (scp) 仅在 command1 完成时运行。让这些并行运行的一种方法是让每个任务后台运行,就像这样......

ssh host command1 &
scp file1 host:/tmp &
ssh host command2 &

所以现在所有三个任务都在后台同时运行。

相关内容