我有一个如下所示的脚本:
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 &
所以现在所有三个任务都在后台同时运行。