捕获通过ssh运行的命令的变量输出

捕获通过ssh运行的命令的变量输出,ssh,scripting,tcl,expect,Ssh,Scripting,Tcl,Expect,我正在使用下面的原始代码启动与设备的连接,运行一些命令,并将值存储到变量“op”中,以便我可以对其进行解析,但看起来似乎即使远程执行commad,也没有设置变量op。我还试图打印expcet buffer的值,但它没有命令o/p的值。这里出了什么问题 spawn /usr/bin/ssh root@[lindex $argv 0] expect { -re ".*Are.*.*yes.*no.*" { send "yes\n" exp_cont

我正在使用下面的原始代码启动与设备的连接,运行一些命令,并将值存储到变量“op”中,以便我可以对其进行解析,但看起来似乎即使远程执行commad,也没有设置变量op。我还试图打印expcet buffer的值,但它没有命令o/p的值。这里出了什么问题

spawn /usr/bin/ssh root@[lindex $argv 0]
    expect {
      -re ".*Are.*.*yes.*no.*" {
        send "yes\n"
        exp_continue
        #look for the password prompt
      }

      "*?assword:*" {
        send "$password\r"
        expect "#"
        send "\n"
      }

    }

    set op [split [send "$cmd\r"]]
    set op $expect_out(buffer);

问题是因为下面的代码

set op [split [send "$cmd\r"]]; # 'send' command won't return the 'cmd' output.
发送命令后,您必须给出下一个
expect
语句,然后只有expect将等待它,然后它将被保存到
expect\u out(缓冲区)

您必须发送命令并等待提示,如下所示

send "$cmd\r"
expect "#"
puts $expect_out(buffer);  #Will print the output of the 'cmd' output now.
set op [ split $expect_out(buffer) ]
这是因为如果在
send
之后没有一个
expect
,我们将错过生成的ssh会话中发生的事情,因为
expect
将假定您只需要发送一个字符串值,而不需要从会话中获取任何其他内容

请记住,如果不使用任何第二个参数而使用
split
,将导致输出被
空格分割

执行命令后要等待的字可能因系统而异。它可以是
$
;所以,确保你给出了正确的答案。或者,您可以为提示符本身提供一个通用模式

set prompt "#|>|:|\\\$"; # We escaped the `$` symbol with backslash to match literal '$'
在发送命令后使用
expect
时,它可以用作

expect -re $prompt; #Using regex to match the pattern
更新:

可能,
#
的匹配在expect缓冲区中已经可用,因此导致了这个问题。为了避免这种情况,您可以尝试在发送命令之前在代码中添加以下行

expect * 
send "$cmd\r"
expect "#"
puts $expect_out(buffer); #This should have the output of the command executed.
这里的*匹配任何东西。这就像是说,“我不在乎你在说什么 在输入缓冲区中。扔掉它。”这个模式总是匹配的,即使 如果什么都没有。记住*匹配任何东西,而空的 绳子就是一切!作为此行为的必然结果,此命令 总是立即返回。它从不等待新数据的到来。信息技术 不必如此,因为它与所有内容都匹配


仍然无法工作,expect\u out缓冲区似乎没有完整的输出。我也试着将matc_max设置为100000,但没有效果。