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

时间:2014-11-04 23:42:34

标签: ssh scripting tcl expect

我使用以下原始代码启动与设备的连接,运行一些命令并将值存储到变量' op'所以我可以解析它,但看起来像是远程执行的commad,变量op没有被设置。此外,我试图打印expcet缓冲区的值,但它没有命令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);

1 个答案:

答案 0 :(得分:0)

问题在于以下代码。

set op [split [send "$cmd\r"]]; # 'send' command won't return the 'cmd' output.

发送命令后,您必须提供下一个expect语句,然后只会等待它,然后将其保存到expect_out(buffer)

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

send "$cmd\r"
expect "#"
puts $expect_out(buffer);  #Will print the output of the 'cmd' output now.
set op [ split $expect_out(buffer) ]

这是因为在expect之后再没有send,我们将错过生成的ssh会话中发生的事情,因为expect将假设您只需要发送一个字符串价值而不期待会议中的其他任何事情。

请记住,使用split而没有任何第二个参数会导致white-space分割输出。

执行命令后要等待的单词可能因系统而异。它可以是#$>:;所以,确保你给出了正确的。或者,您可以为提示提供通用模式

set prompt "#|>|:|\\\$"; # We escaped the `$` symbol with backslash to match literal '$'

在发送命令后使用expect时,可以将其用作

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

更新:

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

expect * 
send "$cmd\r"
expect "#"
puts $expect_out(buffer); #This should have the output of the command executed.
  

这里*匹配任何东西。这就像说,"我不在乎什么   在输入缓冲区中。扔掉它。"这种模式总是匹配,甚至   如果什么都没有请记住*匹配任何东西,而空   字符串是什么!作为此行为的推论,此命令   总是马上回来。它永远不会等待新数据到来。它   没有,因为它匹配一切。