预期输出使用

预期输出使用

我制作了一个脚本,它看起来像这样:

#!/usr/bin/expect -f
set ip [lindex $argv 0];
spawn ssh name@server
expect "assword"
set timeout 0.5
send "password\r"
expect "xxxxx"
set timeout 1
send "telnet $ip\r"
expect "assword"
send "password\r"
expect "xxxxxx"
send "xxxxxxx\r"
.
.
.
.

脚本继续到我的输出显示如下的位置:

Last update from 1.1.1.1 1d06h ago
  Routing Descriptor Blocks:
  * 1.1.1.1 from 2.2.2.2

我需要弄清楚如何提取这个始终唯一的 IP ( 1.1.1.1) 并将其自动转发到我的脚本中,以便我可以继续。

答案1

有两个实例1.1.1.1;假设第一个实例可以匹配,首先需要编写一个简单的脚本来生成所需的输出,并且还包括或多或少由远程设备完成的虚假提示:

#!/usr/bin/env expect
proc prompt {} { puts "prompt"; gets stdin; }
prompt
puts "Last update from 1.1.1.1 1d06h ago"
puts "  Routing Descriptor Blocks:"
puts "  * 1.1.1.1 from 2.2.2.2"
prompt

我称这个脚本为generator;然后还需要另一个脚本来调用该脚本并与之交互。但首先转向如何快速迭代这些脚本的更改;在另一个终端我运行:

$ (echo consume; echo generate) | entr ./consume
...

consume只要consume或脚本发生更改,它就会运行该脚本generate。然后我可以摆弄脚本以与提示进行交互,找到所需的输出,并对其应用正则表达式(阅读手册regexp(n)):

#!/usr/bin/env expect
spawn -noecho ./generate

expect -ex prompt
send -- "before\r"

expect -ex prompt
# this is what I used to confirm that the required prompt block
# had been matched
#puts ">>>$expect_out(buffer)<<<"

regexp {Last update from ([^ ]+) } $expect_out(buffer) unused theip
puts ">>>$theip<<<"

send -- "after\r"
expect eof

此方法假设所需的输出由提示支撑;另一种选择是使用正则表达式的expectLast update ...,但这可能更复杂。此外,此 IP 地址匹配实际上可以匹配任何内容;如果您需要验证文本是否确实是 IP 地址,请使用更精确的正则表达式。

其他问题:

  • 你的超时时间非常短;如果所涉及的任何系统或网络速度缓慢,并且输出需要比给定的超时时间更长的时间才能到达,会发生什么情况?
  • 没有太多的错误检查,如果系统ssh抛出主机密钥错误或提示,或者......

相关内容