复制 ssh 并在一个会话中执行命令

复制 ssh 并在一个会话中执行命令

可能的重复:
使用已建立的 SSH 通道

这是我的同步脚本:

ssh [email protected] /etc/init.d/some_service stop
scp [email protected]:/var/some_service/events ./events
scp ./new_data [email protected]:/var/some_service/new_data
ssh [email protected] /etc/init.d/some_service start

正如您所看到的,它停止服务,使用 scp 执行一些副本,然后重新启动服务。

问题是:它连续“消耗”4 个“类似”的 ssh 连接。

有没有一种方法可以使用一个物理 ssh 连接来完成所有工作?

答案1

您可以考虑使用 ssh 连接共享:

Host *.some-domain
ControlMaster auto
ControlPath ~/.ssh/master-%r@%h:%p

您只需连接一次到目的地,并将 ssh 进程置于后台。然后执行其他命令,最后杀死第一个进程。

或者,您可以尝试将一堆操作封装在一个 ssh 连接中。

例如,假设您有一个目录:

 mycommands
 |
 +- run
 +- new_data

然后您可以将此数据打包到 tar 中并将其发送到您的脚本:

tar cf - -C mycommands . | ssh localhost 'D=`mktemp -d`; tar xf - -C $D; $D/run'

现在您的run脚本可以访问所有输入数据(这里我们只有new_data示例中的数据)。为了坚持你的例子,下面是 run脚本:

#!/bin/sh
BASE=`dirname $0`

/etc/init.d/some_service stop
cat /var/some_service/events

mv $BASE/new_data /var/some_service/new_data
/etc/init.d/some_service start

rm -rf $BASE

所以,现在您只需保存文件events

tar cf - -C mycommands . | ssh localhost 'D=`mktemp -d`; tar xf - -C $D; $D/run' >./events

更一般地,您可以让run脚本生成一个 tar,然后通过管道ssh输入 tar 以在本地解压它。

答案2

您可以将此逻辑移至目标服务器上运行的脚本,然后使用单个 SSH 命令执行它。想必这并不理想,否则你已经这样做了:)

您可以使用 SSH 主连接来降低打开新 SSH 连接的成本。这意味着您的第一个 SSH 命令将像平常一样打开一个新连接。与同一服务器的后续连接将重用此现有连接,从而节省创建三个附加连接的开销。

这里有一个很好的设置指南:http://www.linuxjournal.com/content/speed-multiple-ssh-connections-same-server

答案3

这假设本地服务器信任远程服务器运行没有密码的命令,否则它将无法工作,因为您正在运行所谓的无头连接,无法提供输入

ssh remoteserver "/etc/init.d/some_service stop; scp /var/some_service/events localhost:${PWD}/events; scp localserver:${PWD}/new_data /var/some_service/new_data; /etc/init.d/some_service start"

上述所有代码都需要位于终端上的一个连续行上,或者如果您从脚本内部运行它,则这应该全部是一个命令,而不是用换行符分隔。

如果您有从远程服务器到本地服务器的可信密钥对,我看不出有任何理由这不起作用。

相关内容