【问题标题】:Expect Script: Parse Specific Info From Cisco CLI期望脚本:从 Cisco CLI 解析特定信息
【发布时间】:2014-07-17 23:42:14
【问题描述】:

我是 Expect 脚本的新手,并试图解析 Cisco 路由器 ACL 输出。

我专门尝试解析前 2 行注释之间的 IP 地址。非常感谢任何帮助。


这是我的随机尝试之一。它从 ACL 中解析 IP 地址,但不会停在第二行:

send "show run | section ip access-list extended OUTSIDE\r\n"
set ip {}
    expect {
       "remark ##### DENIED HOSTS #####\r\n" {
          expect -re {(\d+\.\d+\.\d+\.\d+)} {
            set ip "${ip}$expect_out(0,string)"
            puts $ip
            set ip {}
            exp_continue
            }
          }
    }

脚本不仅没有像我希望的那样停在第二个注释行,而且它似乎没有退出点并等待 Expect 超时。

随机样本 ACL 供参考:

ip access-list extended OUTSIDE
 remark ##### DENIED HOSTS #####
 deny   ip host 2.2.2.2 any
 deny   ip host 9.9.9.9 any
 deny   ip host 8.7.6.5 any
 deny   ip host 5.6.7.8 any
 deny   ip host 5.5.5.5 any
 deny   ip host 4.4.4.4 any
 deny   ip host 3.3.3.3 any
 remark ########################
 permit tcp any any eq 22
 deny   ip any any
 permit ip host 2.3.5.1 any

我基本上是想解析从2.2.2.2到3.3.3.3的地址,但是一旦脚本到达第二个注释行就退出。

【问题讨论】:

  • 请格式化您的帖子。在这里阅读一篇文章并不好玩......

标签: parsing expect cisco command-line-interface


【解决方案1】:

使用exp_continue,添加我们希望从期望终止的情况总是更好。因此,如果出口案例到达,我们可以从期望中终止。否则,显然timeout 会发生。

例如

expect{ 
    “p” {send “\r\r\r”; exp_continue} 
    “+” {incr foo; exp_continue} 
    “i” {puts "test"; exp_continue} 
    “quit” exit 
}

如你所见,如果出现'quit'这个词,那么它就会退出。

让我们来回答你的问题。当单词
'remark ########################' 到达时,您需要退出期望。但是,如果我们这样编码,

expect {
   "remark ##### DENIED HOSTS #####\r\n" {
      expect {

            "remark ########################" {exit}
            -re {(\d+\.\d+\.\d+\.\d+)} {
                                    set ip "${ip}$expect_out(0,string)"
                                    puts "-->$ip"
                                    set ip {}
                                    exp_continue
                    }
            }
    }
}

程序将在 ip 解析过程中终止 expect

您可以更好地获取整个输出并尝试将其解析为一个单独的变量,而不是这样做,以避免预期的开销。

send "show run | section ip access-list extended OUTSIDE\r\n"
expect {
    -re {deny\s+ip\s+host\s+(.*)remark} { puts "match found" } 
    timeout {puts "timeout happened"}
}

现在我们有了匹配项,它将在变量 expect_out(1,string) 中可用。

然后我们可以在变量中做正则表达式,解析ip地址。

puts [ regexp -inline -all {\d.\d.\d.\d} $expect_out(1,string) ]

您可以尝试以下另一种方法。您可以简单地获取整个输出,然后执行regexp,而不是在期望中执行正则表达式。

send "sh run | section ip access-list extended OUTSIDE\r"
#Assuming your router's hostname is `Router`
expect "Router#"
#output will hold the command output.
set output  expect_out(buffer)
puts $output
set ip_list [regexp -inline -all {\d.\d.\d.\d} $output]
foreach ip $ip_list { 
    puts $ip
}

【讨论】:

  • 抱歉...不小心以某种方式回复了您的回复:-)。也在这里列出。没有看到删除我所做的编辑更新的选项。
  • 谢谢,你是个疯狂的天才 :-)。我看到的唯一问题是它出于某种原因打印了两次 IP 地址,并且还打印了 2.3.5.1,这是在第二条备注行之后列出的“允许 ip 主机”地址。有任何想法吗?另外,知道如何在打印出的每个 IP 地址后添加换行符吗?我尝试在 puts 行的各个位置添加“\n”,但没有运气。这是我使用您的更新得到的输出:匹配找到 2.2.2.2 9.9.9.9 8.7.6.5 5.6.7.8 5.5.5.5 4.4.4.4 3.3.3.3 2.3.5.1 2.2.2.2 9.9.9.9 8.7.6.5 5.6.7.8 5.5.5.5 4.4.4.4 3.3.3.3
  • 你能尝试打印expect_out(0,string)expect_out(1,string)的值吗?
  • 您也可以在评论部分进行格式化。点击“添加评论”按钮附近的“帮助”链接。
  • 更新...您提供的最后一个代码确实可以工作,而无需两次打印地址。事实证明,我有 2 个 ACL 都以名称“OUTSIDE”开头,所以这就是我看到重复地址的原因!!!唯一的问题是所有地址都是从 ACL 打印的,而不仅仅是第二个 ACL 备注行之前的地址。
【解决方案2】:

感谢迪内什!!!

在这里重新发布最终的工作代码(或 Dinesh 提供的代码的混合),这样它就不会在上面的所有文本中丢失(因此我可以比在评论部分更容易地格式化)。

send "show run | section ip access-list extended OUTSIDE\n"

expect -re {remark(.*)remark}
set output $expect_out(buffer)
#puts $output
puts "\r"
set ip_list [regexp -inline -all {\d.\d.\d.\d} $output]
foreach ip $ip_list {
  puts $ip
}

我注释掉了第一个 puts 行,但在测试时将其留在那里以查看实际存储在 $output 中的内容。

这是从路由器 CLI 解析的 ACL:

ip access-list extended OUTSIDE
 remark ##### DENIED HOSTS #####
 deny   ip host 2.2.2.2 any
 deny   ip host 9.9.9.9 any
 deny   ip host 8.7.6.5 any
 deny   ip host 5.6.7.8 any
 deny   ip host 5.5.5.5 any
 deny   ip host 4.4.4.4 any
 deny   ip host 3.3.3.3 any
 remark ########################
 permit tcp any any eq 22
 deny   ip host 82.28.82.28 any
 permit ip host 2.3.5.1 any

我知道,这是一个完全复杂的 ACL,但它非常适合测试。

这是解析 ACL 后的 Expect 脚本输出:

2.2.2.2
9.9.9.9
8.7.6.5
5.6.7.8
5.5.5.5
4.4.4.4
3.3.3.3

第二个 ACL 备注行之后的任何/所有 IP 地址都将根据需要被忽略!

谢谢迪内什!

【讨论】:

  • 伟大的 Mr.Expect 的专家 :)
  • 再次感谢!非常感谢您的帮助!
【解决方案3】:

你为什么不将 perl 与 Net::Telnet::Cisco 一起使用?

https://metacpan.org/pod/Net::Telnet::Cisco

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-09
    • 1970-01-01
    • 2020-12-28
    • 2022-11-18
    • 1970-01-01
    相关资源
    最近更新 更多