![复制 ssh 并在一个会话中执行命令](https://linux22.com/image/43647/%E5%A4%8D%E5%88%B6%20ssh%20%E5%B9%B6%E5%9C%A8%E4%B8%80%E4%B8%AA%E4%BC%9A%E8%AF%9D%E4%B8%AD%E6%89%A7%E8%A1%8C%E5%91%BD%E4%BB%A4.png)
可能的重复:
使用已建立的 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"
上述所有代码都需要位于终端上的一个连续行上,或者如果您从脚本内部运行它,则这应该全部是一个命令,而不是用换行符分隔。
如果您有从远程服务器到本地服务器的可信密钥对,我看不出有任何理由这不起作用。