【问题标题】:EXPECT Script for Cisco / Juniper Config Backup思科/瞻博网络配置备份的 EXPECT 脚本
【发布时间】:2018-04-11 17:56:41
【问题描述】:

首先我作为脚本初学者问这个问题,目前我有一个期望脚本,它会自动登录到预定义的 Cisco 设备并运行某些命令,我​​想更新我的脚本,以便这个脚本也可以备份 Juniper 设备.

理想情况下,我希望脚本执行的操作是(在伪代码中)

      login / send credentials
      expect prompt
      send command "show version"
      if output contains "JUNOS" then
                send command 1
                send command 2
                send command 3
      otherwise if output contains "Cisco" then
                send command 1
                send command 2
                send command 3

很抱歉,如果以前有人问过这个问题,但我已经尝试过搜索和搜索,但如果有人可以提供帮助,我将无法找到答案,我将不胜感激。我还包含了我当前的期望脚本供您参考(此脚本由 BASH 脚本调用)

set timeout 5
set hostname [lindex $argv 0]
set username "user"
set password "pass"

spawn ssh $username@$hostname

expect "Password:"
send "$password\n"
expect "#" {
send "terminal length 0\n"
send "show running-config\n"
expect "end\r"
send "\n"
send "exit\n"
}

---- 更新 ---

感谢您的意见 Dinesh - 我已更新我的脚本以包含您提供的内容(如下所示)

set timeout 5
set hostname [lindex $argv 0]
set username "user"
set password "pass"
set prompt "(>|#|\\\$) $"

spawn ssh $username@$hostname


expect "*assword:"
send $password\r
send \r
expect -re $prompt {

    send "show version\r"
    expect -re $prompt
    expect *;

    set output $expect_out(buffer);

    #Basic string check logic with Tcl
    if { [string first "JUNOS" $output ]!=-1 } {
        send "show configuration | display set | no-more"
    expect -re $prompt
    send "exit\r"
    } else {
    send "terminal length 0\r"
    expect -re $prompt
    send "show run\r"
    expect "end"
    send \r
    expect -re $prompt
    send "exit\r"
    }
}

但是,当我运行此脚本时,我遇到的问题是“显示版本”的输出似乎与我的“字符串检查”不匹配,因此脚本忽略了“if”语句并继续执行“其他”声明。

“show version”命令的输出如下 - 我需要修改什么才能匹配“JUNOS”字符串?

user@host> show version
Hostname: host
Model: srx240h
JUNOS Software Release [11.4R7.5]

--- 编辑 2:脚本输出

05c4rw@testpc:~/script$ ./ssh.sh
spawn ssh user@juniperhost
## LOGIN BANNER - Removed for brevity

user@juniperhost's password:
--- JUNOS 11.4R7.5 built 2013-03-01 11:40:03 UTC
user@juniperhost> show version
Hostname: juniperhost
Model: srx240h
JUNOS Software Release [11.4R7.5]

user@juniperhost> show configuration | display set | no-more
set version 11.4R7.5

## *** OUTPUT REMOVED FOR BREVITY / PRIVACY ***

## *** END OF OUTPUT from previous command

 user@juniper> spawn ssh user@ciscohost
 password:
 ## LOGIN BANNER - removed for brevitiy

 ciscohost#05c4rw@testpc:~/script$

【问题讨论】:

  • 在发送show version之前放置代码expect *并打印output的值。在这里更新一样。
  • 嗨 Dinesh,感谢您更新了配置,现在它已成功运行“if”语句,但是“else”语句似乎不起作用 - 作为测试,我有两个列表中的设备,它首先自动登录到瞻博网络,然后是思科 - 在成功完成瞻博网络部分后(如果),它登录到思科设备并在退出前坐在提示符中(不发出任何命令)跨度>
  • 在这种情况下,打印输出的值(只是为了方便我们知道)并在转到if-else 循环之前检查它包含的内容。
  • 由于格式问题,我已将输出放在主要问题中,谢谢。
  • 我的意思是打印变量output的值。代码不能跳过if-else 循环。代码流应该使用ifelse

标签: configuration scripting expect cisco


【解决方案1】:
set timeout 5
set hostname [lindex $argv 0]
set username "user"
set password "pass"

spawn ssh $username@$hostname


expect "Password:"
send "$password\r"
expect "#" {

    send "terminal length 0\r"
    expect "#"
    # This is to clean up the previous expect_out(buffer) content
    # So that, we can get the exact output what we need.
    expect *;         
    send "show running-config\r"
    expect "end"

    #Now, the content of 'expect_out(buffer)' has the whole 'show run' output
    set output $expect_out(buffer);

    #Basic string check logic with Tcl  
    if { [string first "JUNOS" $output ]!=-1 } {
           # Apply your logic here
           # send "command1"
           # expect "#"
    } else {
           # Same as above        

           # I assume, there are 2 possibilities. So, keeping 'else' part alone.
           # Have 'else if', if you have more than 2.

    }
}

请注意,脚本发送的每一行都以\r 结束。这表示一个返回字符,如果您在 shell 中输入这些行,这正是您要按下的字符,所以这正是 Expect 必须发送的内容。终止向进程发送命令后跟\n 是一个常见错误。在这种情况下,\n 表示换行符。您不会以换行方式以交互方式结束行。所以Expect 也不能。所以,请始终使用\r

如果您有兴趣了解更多有关为什么需要expect * 的信息,可以查看here。 (这是一个单独的故事)

我可以看到在您的示例中有些命令仅与 send 一起使用。基本上,expect 将使用两个可行的命令,例如sendexpect。在这种情况下,如果使用send,那么之后必须使用expect(在大多数情况下)。 (反之亦然不是强制性的)

这是因为如果不这样做,我们将错过生成过程中发生的事情,因为expect 会假设您只需要发送一个字符串值,而不期待会话中的任何其他内容。

【讨论】:

  • 感谢 Dinesh 的深入回复,由于此处回复的字符数限制,我已用结果更新了我原来的问题。
【解决方案2】:

这可能不是您想要的,但我想我会发布它以防万一。

您可能想研究 Rancid 之类的东西,而不是拥有那些脚本。 Rancid 不仅会备份您的设备配置,它还会以预定义的时间间隔为您提供它管理的设备的差异(例如,如果您将时间间隔设置为 15 分钟,rancid 将每 15 分钟登录一次您的设备抓取配置,备份它们并与以前的版本进行差异并显示差异)

【讨论】:

  • @thanksd rancid 更像是一种工具,而不是代码片段。您可以在这里获取更多详细信息shrubbery.net/rancid
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-01
  • 1970-01-01
  • 2022-12-04
  • 2012-02-07
  • 2018-01-29
  • 1970-01-01
相关资源
最近更新 更多