一、需求分析:某园区网络可管理的交换机大约有几十台,因运维工作需要,应定期进行配置备份,若每次手工备份的话费时费力,考虑开发批量备份功能。

二、思路:

1、所有交换机都是telnet方式登录,考虑使用一台linux虚拟机做自动备份管理机,使用shell和expect软件进行管理程序开发。

2、园区网络交换机配置技术类似华为和思科,交换机的登录模式有三种:类思科交换机登录需要用户名、密码和en密码;类华为交换机的登录需要用户名和密码;类华为的某型号交换机登录只需要密码。

3、程序结构

  

三、程序代码

方法一:(取消备份文件奇异字符的代码放在shell程序中)

1、交换机参数列表文件:swhosts.txt

[root@localhost ~]# vi swhosts.txt
10.10.2.26|username|password|enpassword
10.10.2.28|username|password|null
10.10.3.51|null|password|null

 

2、Shell程序文件:sw.sh

[root@localhost ~]# vi sw.sh
#!/bin/bash
for line in `cat /root/swhosts.txt`
do
   ip=`echo $line | awk -F "|" '{print $1}'`
   login=`echo $line | awk -F "|" '{print $2}'`
   password=`echo $line | awk -F "|" '{print $3}'`
   enpassword=`echo $line | awk -F "|" '{print $4}'`
   erabadsym1="\s\+----\s\+More\s\+----\^[\[42D\s\+\^[\[42D"

#特殊字符^[不能拷贝使用,只能使用键盘输入,方法:CTRL+V+[,类似的特殊字符都可以参照此CTRL+V+字符的方式进行输入;“\s”代表空格,“\+”表示一个或多个前面的字符。“\s\+”表示一个或多个空格。

erabadsym2="\s\+--More--\s\+\^H\+\s\+\^H\+"
#“\^H\+”表示一个或多个“^H”字符
   filename="/root/swconfig/`date +%Y-%m-%d`.$ip.txt"
   /root/sw.exp $ip $login $password $enpassword $filename
    if [ -f $filename ]; then
      if [ $enpassword == "null" ];then
 
       sed -i s/$erabadsym1/""/g $filename
      else
       sed -i s/$erabadsym2/""/g $filename
      fi
    else
      echo `clock` >> /root/swconfig/error.log
      echo "The ip $ip is not arrive! at " `clock` >> /root/swconfig/error.log
      echo "The ip $ip is not arrive!" | mail -s "$ip error!" sfccl@qq.com
    fi
 
done

 

3、Expect程序文件:sw.exp

[root@localhost ~]# vi sw.exp
#!/usr/bin/expect
 
if { $argc != 5} {
   send_user "用法: $argv0 < ip > < login > < password > < enpassword > < filename >\n"
   exit
}

 

 

set timeout 3
set TERM ANSI
 
set IPADD [lindex $argv 0]
set LOGIN [lindex $argv 1]
set PASSWD [lindex $argv 2]
set ENPASSWD [lindex $argv 3]
set FILENAME [lindex $argv 4]
set PROMPTSYM1 "*#"
set PROMPTSYM2 "*>"
set CONCMD1 "sh run\r"
set CONCMD2 "dis cu\r"
set EXIT1 "exit\r"
set EXIT2 "quit\r"
 
#模拟按空格键子程序
proc dospace { Filename CONCMD PROMPTSYM EXITn} {
log_file $Filename
send $CONCMD
while (1) {
   sleep 1
   expect {
      "*More*" { send " "}
      $PROMPTSYM { break }
   }
}
send $EXITn
#expect eof
interact
}
 
#交换机登录子程序
proc dologin { username password } {
  expect {
     "*sername:" { send "$username\r"; exp_continue}
     "*assword:" { send "$password\r"; exp_continue}
  }
}
 
 
#测试目标交换机是否可达,可达才能进入获取配置进程。
spawn ping -c 3 $IPADD
sleep 3
expect {
  "64 bytes*" {send_user "the ip is ok!\n"}
  timeout { send_user "the ip ip is bad!\n" ;exit }
  eof { exit }
}
 
#获取交换机配置主程序
spawn telnet
expect "telnet>"
send "open $IPADD\r"
sleep 5
 
if { $ENPASSWD != "null" } {
dologin $LOGIN $PASSWD
 
expect {
   $PROMPTSYM2  { send "en\r";exp_continue}
   "*assword:" { send "$ENPASSWD\r";exp_continue}
}
sleep 1
expect $PROMPTSYM1
dospace $FILENAME $CONCMD1 $PROMPTSYM1 $EXIT1
}
 
if { $ENPASSWD == "null" } {
dologin $LOGIN $PASSWD
sleep 1
expect $PROMPTSYM2
dospace $FILENAME $CONCMD2 $PROMPTSYM2 $EXIT2
}



 



方法二:(取消备份文件奇异字符的代码放在exp程序中)



 



(1)shell程序sw1.sh的代码:



[root@localhost ~]# vi sw1.sh 
  
 
  

    #!/usr/bin/sh 
  
 
  

      
  
 
  

    for line in `cat /root/swhosts.txt` 
  
 
  

    do 
  
 
  

          IP=`echo $line | awk -F '|' '{print $1}'` 
  
 
  

          ID=`echo $line | awk -F '|' '{print $2}'` 
  
 
  

          PASSWD=`echo $line | awk -F '|' '{print $3}'` 
  
 
  

          ENPASSWD=`echo $line | awk -F '|' '{print $4}'` 
  
 
  

    #      echo $IP,$ID,$PASSWD,$ENPASSWD 
  
 
  

          /root/sw1.exp $IP $ID $PASSWD $ENPASSWD 
  
 
  

    done



 



(2)exp程序sw1.exp的代码:



[root@localhost ~]# vi sw1.exp 
  
 
  

    #!/usr/bin/expect 
  
 
  

    if { $argc != 4 } { 
  
 
  

        send_user "用法:$argv0 < ip > < id > < password > < enpassword > \n" 
  
 
  

        exit 
  
 
  

    } 
  
 
  

      
  
 
  

    set timeout 1 
  
 
  

    set TERM ANSI 
  
 
  

      
  
 
  

    set IP [lindex $argv 0] 
  
 
  

    #send_user $IP\n 
  
 
  

    set ID [lindex $argv 1] 
  
 
  

    set PASSWD [lindex $argv 2] 
  
 
  

    set ENPASSWD [lindex $argv 3] 
  
 
  

    set SYM1 "*>" 
  
 
  

    set SYM2 "*#" 
  
 
  

    set QUITSYM1 "exit\r" 
  
 
  

    set QUITSYM2 "quit\r" 
  
 
  

    set FILE "/root/swconfig1/[exec date +%F-%H:%M:%S].$IP.txt" 
  
 
  

    set QIYISYM1 \15 
  
 
  

    set QIYISYM2 .*\115\157\162\145.*\10 
  
 
  

    set QIYISYM3 .*\115\157\162\145.*\33.\64\62\104 
  
 
  

    #\15是^M的八进制码,相应的115、157、162、145对应More,\10对应^H,\33对应^[,\64\62\104对应42D 
  
 
  

      
  
 
  

    proc login {id password} { 
  
 
  

      expect { 
  
 
  

      "*sername:" {send $id\r;exp_continue} 
  
 
  

      "*assword:" {send $password\r} 
  
 
  

      } 
  
 
  

    } 
  
 
  

      
  
 
  

    proc dospace {sym quitsym} { 
  
 
  

      while (1) { 
  
 
  

       send " " 
  
 
  

       sleep 1 
  
 
  

       expect { 
  
 
  

         "*More*" {send ""} 
  
 
  

         "$sym" { break } 
  
 
  

       } 
  
 
  

      } 
  
 
  

     send $quitsym 
  
 
  

    # expect eof 
  
 
  

     interact 
  
 
  

    } 
  
 
  

      
  
 
  

    spawn ping -c 3 $IP 
  
 
  

    sleep 3 
  
 
  

    expect { 
  
 
  

      "64 bytes" { send_user  "The ip is ok!\n"} 
  
 
  

      timeout {exit} 
  
 
  

      eof {exit} 
  
 
  

    } 
  
 
  

    sleep 1 
  
 
  

      
  
 
  

    spawn telnet 
  
 
  

    expect "telnet>" 
  
 
  

    send "open $IP\r" 
  
 
  

    sleep 8 
  
 
  

    login $ID $PASSWD 
  
 
  

    sleep 1 
  
 
  

    expect $SYM1 
  
 
  

    if { $ENPASSWD != "null"} { 
  
 
  

       send "en\r" 
  
 
  

       expect "Password:" 
  
 
  

       send $ENPASSWD\r 
  
 
  

       expect $SYM2 
  
 
  

    #   log_file /root/swconfig1/[exec date "+%F"].$IP.txt 
  
 
  

    #   log_file /root/swconfig1/[clock format [clock seconds] -format "%Y-%m-%d"].$IP.txt 
  
 
  

       log_file $FILE 
  
 
  

       sleep 2 
  
 
  

       send "sh run\r" 
  
 
  

       dospace $SYM2 $QUITSYM1 
  
 
  

       exec sed -i s/$QIYISYM1//g $FILE 
  
 
  

       exec sed -i s/$QIYISYM2//g $FILE 
  
 
  

    } 
  
 
  

      
  
 
  

    log_file $FILE 
  
 
  

    sleep 2 
  
 
  

    send "dis cu\r" 
  
 
  

    dospace $SYM1 $QUITSYM2 
  
 
  

    exec sed -i s/$QIYISYM3//g $FILE



 



 

4、修改运行程序文件属性,增加执行权限

[root@localhost ~]# chmod +x sw.sh
[root@localhost ~]# chmod +x sw.exp

 

5、配置定时运行

[root@localhost ~]# crontab -e
...
55 23 * * * /root/sw.sh

 

#说明:每晚23:55启动自动备份程序sw.sh

 

四、测试

2019-1-31测试通过,在/root/swconfig目录下正常生成备份文件。

 小结:

1、使用shell和expect工具进行交换机配置备份是比较容易实现的方法。

2、在shell中的编程和在expect中的编程有较大的差异,比如,变量赋值就明显不同,要特别注意。

3、在expect中的正则表达式有许多细节需要注意,特别是中括号的使用要小心。