首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在expect脚本中显示cdp邻居

在expect脚本中显示cdp邻居
EN

Stack Overflow用户
提问于 2012-11-15 01:18:00
回答 1查看 3K关注 0票数 3

一般来说,我对脚本编程非常陌生。我正在编写一个expect脚本,该脚本ssh进入Cisco交换机,并运行"show cdp neighbors“命令来获取连接到该交换机的所有设备的列表。然后,我将输出保存到一个变量中并退出ssh会话。我在包含的文件中设置了用户名和密码。

代码语言:javascript
复制
#!/usr/bin/expect -f
#exp_internal 1

source accountfile
set timeout 10
spawn $env(SHELL)
expect "#"
send "ssh $USERNAME@<hostname>\r"
expect {
  "continue connecting" {
    send_user "Adding host to ssh known hosts list...\n"
    send "yes\n"
    exp_continue
  }
  "Do you want to change the host key on disk" {
    send_user "Changing host key on disk...\n"
    send "yes\n"
    exp_continue
  }
  "assword:" {
    send "$PASSWORD\r"
  }
}
expect "#"
send "term len 0\r"
expect "#"
send "show cdp neighbors\r"
expect "#"
set result $expect_out(buffer)
send "exit\r"
expect "#"

因此,我想使用$result并查找包含‘R’的行,并将这些行保存到一个文件中(两边带有空格的R表示路由器,这正是我感兴趣的)

问题是,如果连接的设备的名称很长,它会将设备的名称放在一行中,然后将设备的其余数据放在下一行中。因此,如果我匹配‘R’字符串,我将不会得到设备的名称,因为名称在前一行。

代码语言:javascript
复制
Device ID        Local Intrfce     Holdtme     Capability Platform  Port ID
...
<device_name_really_long>
                 Gig 2/0/52        171             R S I  WS-C6509  Gig 3/14
<device_name2>   Gig 2/0/1         131             H P M  IP Phone  Port 1
...

有什么想法吗?可能有一个正则表达式可以做到这一点,但我不知道正则表达式。

已解决:感谢Glenn Jackman

我最终不得不添加一个expect条件来检查我是否有一个完整的缓冲区,所以我的最终代码如下所示:

代码语言:javascript
复制
#!/usr/bin/expect
#exp_internal 1
match_max 10000
set expect_out(buffer) {}
set timeout 30

source accountfile
spawn $env(SHELL)
expect "#"
send "ssh $USERNAME@ol2110-3750stack.sw.network.local\r"
expect {
    "continue connecting" {
        send_user "Adding host to ssh known hosts list...\n"
        send "yes\n"
        exp_continue
    }
    "Do you want to change the host key on disk" {
        send_user "Changing host key on disk...\n"
        send "yes\n"
        exp_continue
    }
    "assword:" {
        send "$PASSWORD\r"
    }
}
expect "#"
send "term len 0\r"
expect "#"
send "show cdp neighbors\r"
set result ""
expect {
    {full_buffer} {
        puts "====== FULL BUFFER ======"
        append result $expect_out(buffer)
        exp_continue
    }
    "#" {
        append result $expect_out(buffer)
    }
}
send "exit\r"
expect "#"
set devices [list]
set current_device ""
set lines [split $result "\n"]
foreach line $lines {
    set line [string trim $line]
    if {[llength $line] == 1} {
        set current_device $line
        continue
    }
    set line "$current_device$line\n"
    if {[string match {* R *} $line]} {
        lappend devices $line
    }
    set current_device ""
}

puts $devices
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-15 05:40:21

代码语言:javascript
复制
set devices [list]
set current_device ""
foreach line [split $result \n] {
    if {[llength [split [string trim $line]]] == 1} {
        set current_device $line
        continue
    }
    set line "$current_device$line"
    if {[string match {* R *} $line]} {
        lappend devices $line
    }
    set current_device ""
}

# devices list should now contain "joined" routers.
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13383821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档