在多跳SSH连接上重新建立交互shell



我有一个用例,从主机"a"我需要通过主机"B"one_answers"C"ssh到主机"D"(我希望能够将该解决方案应用于尽可能多的中间主机):

A===>B===>C===>D

一旦建立到D的连接,我想运行命令列表["comm1"、"comm2"、"omm3"],并在主机A上以["output1"、"output2"、"outut3"]的形式接收响应。我想出的唯一策略是,一旦你到达主机D:

  1. 执行连接.invoke_shell()
  2. 在中发送comm1,轮询通道以获取输出,收集响应并将其插入空列表
  3. 关闭由connection.invoke_shell()创建的通道
  4. 构建一个全新的交互式shell通道
  5. 对comm2和comm3重复步骤1至5

当我开发时,我意识到试图重新建立交互式shell通道会导致EOF错误。我有一种预感,在步骤3中关闭通道会终止从主机a到主机D的整个SSH会话。

然而,必须关闭通道,并为每个命令启动一个新的交互式shell。否则,您将把通道的完整输出(包含所有3个命令的输出)读取为一大块文本,然后必须使用屏幕抓取来处理,这并不理想。上面的算法可能吗?如果是,如何用paramiko实现它,为什么我会得到EOFError异常?

我也尝试使用Fabric来实现这一点。它适用于某些设备,但不适用于思科的设备。原因是Fabric使用了paramiko的ssh远程命令执行功能,这也是一些Cisco设备不支持的(请查看client.exc_command)。因此,交互式会话是唯一的选择。

为了简单起见,考虑无跳情况:

$ ssh -i key user@host 'echo command; echo control'
command
control
$ ssh -i key user@host 'echo command; echo control' >/dev/null
$ ssh -i key user@host 'echo command; echo 1>&2 control' >/dev/null
control

换句话说,我们有两个输出通道。。。

最新更新