使用期望脚本将多行放在一行上

putting multiple lines on one line using expect script

我写了一个 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#

这里是 expect 脚本:

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'。

测试 - 正常

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 为每个设备匹配多行并将输出保存在同一行?

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

在你的例子中,变量 route 已经嵌入了换行符,从而导致它以这种方式打印。

您可以在 route 变量中用 space 替换所有换行符,或者将它们拆分为列表,然后将其写入文件。

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

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

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

那么您期望 \r\nip\s+route.* 当前符合您的需求。假设,如果输出很大或需要更多时间才能完成,那么它可能会失败。为了有一个安全的方法,你可以使用 exp_continue 来匹配每个出现的行。