将double-ssh(ssh两次)会话的输出捕获为BASH变量

时间:2016-10-27 20:19:43

标签: bash ssh

我想捕获ssh会话的输出。但是,我首先需要ssh 两次(从我的本地计算机到远程服务器的远程门户),然后运行命令并捕获输出。

逐行完成,我会这样做:

ssh name@remote.portal.com
ssh remote.server.com
remote.command.sh

我尝试了以下内容:

server=remote.server.com  ##define in the script, since it varies
sshoutput=$(ssh -tt name@remote.portal.com exec "ssh -tt ${server} echo \"test\"")
echo $sshoutput

我希望上面的脚本在最后一个命令后回显“test”。但是,外部ssh提示只是在我输入命令后挂起,一旦我按Ctrl + c或无法输入我的密码,内部ssh会话失败(我相信因为stdout不再打印到屏幕而我不再获取我的密码提示)。

如果我只运行内部命令(即没有“sshoutput = $(”将其保存为变量),那么它可以工作,但(显然)不捕获输出。我也尝试过没有“exec”。

我也尝试将内部ssh保存为变量,如

sshoutput=$(ssh -tt name@portal myvar=$(ssh -tt ${server} echo \"test\"") && echo $myvar)

但是失败了,因为BASH在将内部ssh发送到外部ssh会话之前尝试执行它(我相信),并且无法识别服务器名称。

(我看过https://unix.stackexchange.com/questions/89428/ssh-twice-in-bash-alias-function,但他们只是说“如果使用交互式密码需要更多标志”并且不解决捕获输出问题。

提前感谢您的任何帮助!

1 个答案:

答案 0 :(得分:1)

这里最好的做法是让ssh自己完成跳过你的弹跳主机的工作。

result=$(ssh \
  -o 'ProxyCommand=ssh name@remote.portal.com nc -w 120 %h %p' \
  name@remote.server.com \
  "remote.command.sh")

您可以在~/.ssh/config中自动执行此操作,如下所示:

Host remote.server.com
    ProxyCommand ssh name@remote.portal.com nc -w 120 %h %p

...之后任何ssh remote.server.com命令都会自动跳转到remote.portal.com。 (根据bouncehost上安装的工具,将nc更改为netcat或类似内容。

那就是说,如果你真的想自己做,你可以:

printf -v inner_cmd '%q ' "remote.command.sh"
printf -v outer_cmd '%q ' ssh name@remote.server.com "$inner_cmd"
ssh name@remote.portal.com bash -s <<EOF
$outer_cmd
EOF

...最后一部分可以在命令替换中运行,如下所示:

result=$(ssh name@remote.portal.com bash -s <<EOF
$outer_cmd
EOF
)