2

我有一个包含两列格式为“IP 地址;主机名”的 CSV。我有这段脚本可以打开一个主机文件并登录到交换机/路由器并将配置备份到 tftp 服务器。

现在我需要调整脚本来打开 csv,这样我就可以在交换机上设置主机名。我唯一需要知道的是如何打开 CSV 并从每行中获取两个变量,即 IP 地址和主机名。其余的都没有问题。

    #! /bin/expect

    set timeout 20
    set hostnamefile [lindex $argv 0]
    set tftpip [lindex $argv 1]
    set user [lindex $argv 2]
    set password [lindex $argv 3]
    set prompt "*#"

    set send_slow {10 .001}
    log_user 0

    if {[llength $argv] == 0} {
      send_user "Usage: scriptname hostnamefile \'TFTPserver IP\' username         \'userpassword\'\n"
      exit 1
    }

    ;# -- main activity

    proc dostuff { currenthost {tftpserver 1} } {

       ;# do something with currenthost

       send_user "\n#####\n# $currenthost\n#####\n"

       send -- "copy running-config tftp:\r"
       expect "Address or name of remote host []?"
       send "$tftpserver\r"
       expect "Destination filename*"
       send "\r"
       expect {
           "*bytes copied*" {
           send_user "TFTP copy succeeded\n"
           }
           "*Error*"{
           send_user "TFTP copy failed\n"
           }
       }
       send "\r"
       return
    }

    ;# -- start of task

    set fd [open ./$hostnamefile r]
    set hosts [read -nonewline $fd]
    close $fd


    foreach host [split $hosts "\n" ] {

        spawn /usr/bin/ssh $user@$host

        while (1) {
            expect {

            "no)? " {
               send -- "yes\r"
            }

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

            "*>" {
              send "enable\r"
            }

            "$prompt" {
               dostuff $host $tftpip
               break
            }
          }
       }

       expect "$prompt"
       send -- "exit\r"

    }

    expect eof
4

2 回答 2

1

我设法围绕起到作用的期望脚本构建了一个 bash 脚本。如果有人有更好的方法,请告诉我。

#!/bin/bash
input=./list.csv
oldifs=$ifs
ifs=,
[ ! -f $input ] && { echo "$input file not found"; exit 99; }

if [ $# -ne 2 ]
then
    echo "Usage: scriptname username password"
    exit 1
fi

username=$1
password=$2

while read line
do
eval $(echo "$line" | awk -F';' '{print "ip="$1";hostname="$2}')
#echo $ip
#echo $hostname

/usr/bin/expect - << EndMark
set prompt "*#"
set cprompt "*(config)#"

spawn /usr/bin/ssh $username@$ip

while (1) {
   expect {
       "no)? " {
          send -- "yes\r"
       }
       "*assword*:" {
          send -- "$password\r"
       }
       "*>" {
          send "enable\r"
       }
       "$prompt" {
          break
       }
   }
}
sleep 2

send -- "conf t\r"
expect "$cprompt"
send -- "hostname $hostname\r"
expect "$cprompt"
send -- "end\r"
expect "$prompt"
send -- "copy running-config startup-config\r"
expect "Destination filename*"
send -- "\r"
expect "$prompt"
send -- "exit\r"

send_user "\n#####\n# hostname $hostname\n# set on $ip\n#####\n"
send -- "exit\r"

expect eof

EndMark

done < $input
ifs=$oldifs
于 2012-12-19T09:24:25.390 回答
0

一年后......但它仍然可能有用!

#! /bin/expect

set f [open "list.csv"] #associate your csv to a var
set lines [split [read $f] "\n"] #build a list named "lines": each list item is a line

# create a while loop until "x" reach the length of your list -1
set x 0
while {$x<[expr [llength $lines] -1]} {   
    set line [lindex $lines $x]           
    regexp (.*);(.*) $line match_regex ip host 
    puts $match_regex
    puts $ip
    puts $host
    incr x
}


# set line... # var "line" will be at each cycle an item of your list
# regex...    # split var "line" into 3 vars: 
# "match_regex" will match all the string
# "ip" will match regex included in first "(.*)" 
# "host" regex in the second "(.*)"
于 2018-03-12T17:28:45.743 回答