【问题标题】:Capturing Output to a variable for command run over ssh将输出捕获到通过 ssh 运行的命令的变量
【发布时间】:2014-11-04 23:42:33
【问题描述】:

我正在使用下面的原始代码来启动与设备的连接,运行一些命令并将值存储到变量“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);

【问题讨论】:

    标签: ssh scripting tcl expect


    【解决方案1】:

    问题是因为下面的代码。

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

    发送命令后,你必须给出下一个expect语句,然后只有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) ]
    

    这是因为在send 之后没有更多expect,我们将错过生成的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.
    

    这里的 * 匹配任何东西。这就像说,“我不在乎什么是 在输入缓冲区中。扔掉它。”这种模式总是匹配的,即使 如果什么都没有。记住 * 匹配任何东西,而空的 字符串是什么!作为这种行为的必然结果,这个命令 总是立即返回。它从不等待新数据到达。它 不需要,因为它匹配所有内容。

    【讨论】:

    • 仍然不起作用,expect_out 缓冲区似乎没有完整的输出。我也尝试将 matc_max 设置为 100000,但无济于事。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 2014-09-19
    • 2012-06-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-15
    相关资源
    最近更新 更多