使用expect脚本

时间:2015-07-30 03:59:43

标签: tcl expect

我写了一个expect脚本来验证我是否在cisco路由器上有静态路由。我需要输出线显示在同一行,即使变量匹配多行

以下命令用于cisco设备:

example1#sh run | i ip route
ip route 169.254.0.1 255.255.255.255 Dialer1
ip route 169.254.0.2 255.255.255.255 Dialer2
example1#

这里是期望脚本:

set hostname "example1"
set model "cisco1841"

send "sh run \| i ip route\r" ; sleep 5
expect {
    -re {\r\nip\s+route.*} { 
        set route "$expect_out(0,string)"
        set f [open file.csv a]
        puts -nonewline $f $hostname,$model,$route
        puts $f "\r"
        close $f
    }
    timeout { 
        set route "no static route"
        set f [open file.csv a]
        puts -nonewline $f $hostname,$model,$route
        puts $f "\r"
        close $f
    }
}

这里是变量$ route

ip route 169.254.0.1 255.255.255.255 Dialer1
ip route 169.254.0.2 255.255.255.255 Dialer2
example1#

验证输出文件,这不是我所期望的。 “-nonewline”这个论点不起作用。该文件始终使用换行符。

输出文件:

example1,cisco1841,ip route 169.254.0.1 255.255.255.255 Dialer1
ip route 169.254.0.2 255.255.255.255 Dialer2
example1#

我做了一个测试,问题是因为变量在行尾没有'\ n \ r'。

测试 - NOK

set route "ip route 169.254.0.1 255.255.255.255 Dialer1
ip route 169.254.0.2 255.255.255.255 Dialer2
example1#"

测试 - 确定

set route "ip route 169.254.0.1 255.255.255.255 Dialer1 \
ip route 169.254.0.2 255.255.255.255 Dialer2 \
example1#"

输出文件确定

example1,cisco1841,ip route 169.254.0.1 255.255.255.255 Dialer1 ip route 169.254.0.2 255.255.255.255 Dialer2 example1#

如何使用expect?

为每个设备匹配多行并将输出保存在同一行上

1 个答案:

答案 0 :(得分:1)

默认情况下,puts命令在字符串后输出换行符,但可以通过指定-nonewline开关来抑制此功能。 它永远不会删除已传递的输入字符串中已有的任何现有换行符

在您的情况下,变量route已经嵌入了换行符,从而导致它以这种方式打印。

您可以使用route变量中的空格替换所有换行符,也可以将其拆分为列表,然后将其写入文件。

puts [regsub -all {\n} $route " "]

再观察一次。发送一些命令后,您已使用sleep命令。

send "sh run \| i ip route\r" ; sleep 5

然后您期待\r\nip\s+route.*符合您的需求。假设,如果输出很大或需要更多时间来完成,那么它可能会失败。要采用安全的方法,您可以使用exp_continue来匹配每一行的匹配。