将双ssh(ssh tweeps)会话的输出捕获为BASH变量

将双ssh(ssh tweeps)会话的输出捕获为BASH变量,bash,ssh,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.p

我想捕获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会话之前执行它(我相信),并且服务器名称无法识别

(我已经看过了,但他们只是说“如果使用交互式密码,则需要更多标志”,而没有说明捕获输出)


提前感谢您的帮助!

这里的最佳实践方法是让ssh自己完成跳转您的bouncehost的工作

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
(将
nc
更改为
netcat
或类似命令,适用于bouncehost上安装的工具)


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

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
printf-v内部命令'%q'“remote.command.sh”
printf-v外部命令“%q”sshname@remote.server.com“$internal\u cmd”

sshname@remote.portal.combash-s到目前为止,最好的方法是使用
ProxyCommand
让ssh自己完成设置内部ssh会话的工作。为什么要使用
-tt
?我不确定这对这个问题有什么影响,但似乎没有必要。@ProxyCommand注释:类似于下面的链接?我的上文remote.command.sh实际上设置了一个VNC服务器,并返回要使用的端口(例如“:3”),然后我通过ssh隧道连接到该端口。下面链接中的命令是否会干扰(和/或没有权限)?@cwotta,请在问题本身中包含足够的内容来生成和测试答案,而不是在链接后面(特别是在cyberciti.biz链接后面;我不会用10英尺长的杆子碰它)。也就是说,一般来说,
ProxyCommand
的使用不会干扰其他类型的SSH代理支持。@why-tt:通过查看各种网站,似乎这是必要的,因为我是双重SSH。我会收到“不是真正的终端”-类型错误(无法具体记住),但它似乎不再是一个问题,因为我只是在没有它的情况下进行了测试,它不再存在,尽管我的命令无法执行。如果您总是需要使用代理来访问远程服务器,您可以将其放入
.ssh/config
@CharlesDuffy--Update:我不正确。我使用的是第一个代码块。它不是capt在将输出转换为$result时,它只是将其打印到屏幕上(stdout)——我最初认为它可以工作,因为我在检查之后回显了$result——否则,它可以工作(即,我可以登录并执行命令)。此外,我尝试了最后两个代码块,并立即收到三个“权限被拒绝”错误。这并不重要,因为我没有使用该方法,但我想我会注意到它。您确定要使用经过编辑的第一个代码块吗?第一个版本根本没有捕获(这是留给读者的一个非常明显的练习)…如果它仍然没有捕获,那么您试图捕获的内容很有可能实际上是进入stderr,而不是stdout。在命令替换的结束部分之前放置一个
2>&1
。…对于拒绝权限的错误,使用
set-x
记录本地运行的确切命令,并更改
bash-s
to
bash-x-s
对远程位执行类似操作。并发布输出。如果在需要时将
“remote.command.sh'参数1”“参数2'
传递给printf或类似文件,我不会感到惊讶;在给出日志时,应该是显而易见的。
result=$(ssh name@remote.portal.com bash -s <<EOF
$outer_cmd
EOF
)