我正试图用一些嵌入式Expect脚本编写一个小型bash脚本。我需要更改大约3500交换机的主机名。我有一个csv文件,里面有我的ip地址和新主机名,还有我期望的脚本。如果连接到交换机没有问题,脚本似乎运行得很好。如果我确实从交换机收到"超时"或"拒绝访问",脚本将停止并退出。我需要脚本转到下一个ip地址。
我确实使用了酸腐的clogin进行自动登录。
我是新来的期待和抨击,已经在我最好的朋友"谷歌"上搜索了可能的答案,但找不到答案。
脚本如下:
主机名.exp
#!/usr/bin/expect -f
# Set variables
set DATE [exec date +%F]
set timeout 10
# Log results
log_file -a hostnames-$DATE.log
# Let's go to configure mode
## Read the file
set fid [open ./hostnames.csv]
set content [read $fid]
close $fid
## Split into records on newlines
set records [split $content "n"]
## Iterate over the records
foreach rec $records {
## Split into fields on comma
set fields [split $rec ","]
## Assign fields to variables and print some out...
lassign $fields hostname newname
puts "$hostname"
puts "$newname"
if {$hostname == ""} continue
# Announce which device we are working on and at what time
send_user "n"
send_user ">>>>> Working on $hostname @ [exec date] <<<<<r"
send_user "n"
spawn clogin "$hostnamer"
expect {
timeout { send_user "n Failed to get login promptn"; exit 1 }
eof { send_user "nSSH failure for hostnamen"; exit 1 }
"*-> $"
}
sleep 2
send "conf tn"
expect "#"
send "hostname $newnamen"
expect "#"
send "exitn"
expect "(config)#"
send "write memn"
expect "*#"
send "exitn"
expect ":~$" exit
# Announce which device we are working on and at what time
send_user "n"
send_user ">>>>> Done working on $hostname @ [exec date] <<<<<r"
send_user "n"
}
这是我的csv文件
主机名.csv
10.10.1.1,newhostname1
172.16.1.2,newhostname2
192.168.45.150,newhostname3
如果有任何帮助,我将不胜感激。
谢谢
你好Dinesh
感谢您的回复。
我使用了您提供的第一个没有"句柄"部分的代码。如果登录失败,它现在将转到下一个ip地址,但是,它不会在良好的登录中运行我的命令。登录172.16.1.2是唯一可用的连接。其他的是测试故障转移。
$**expect hostnames.exp**
10.10.1.1
newhostname1
>>>>> Working on 10.10.1.1 @ Wed Oct 1 11:59:09 SAST 2014 <<<<<
spawn clogin 10.10.1.1
10.10.1.1
in /home/*****/.cloginrc.0.1.1
SSH failure for hostname for 10.10.1.1
172.16.1.2
newhostname2
>>>>> Working on 172.16.1.2 @ Wed Oct 1 11:59:09 SAST 2014 <<<<<
spawn clogin 172.16.1.2
172.16.1.2
spawn telnet 172.16.1.2
Trying 172.16.1.2...
.onnected to 172.16.1.2
Escape character is '^]'.
User Access Verification
Username: *****
Password:
SR_Test_SW#
SR_Test_SW#
Failed to get login prompt for 172.16.1.2
192.168.45.150
newhostname3
>>>>> Working on 192.168.45.150 @ Wed Oct 1 11:59:11 SAST 2014 <<<<<
spawn clogin 192.168.45.150
192.168.45.150
spawn telnet 192.168.45.150
Trying 192.168.45.150...
Failed to get login prompt for 192.168.45.150
$
我确实用"handle"部分尝试了您的第二个代码,但这也给了我错误。
如果你需要的话,我会给你一个输出。
谢谢你抽出时间。
只需在timeout
和eof
的预期下使用continue
,而不是exit 1
expect {
timeout {
send_user "n Failed to get login prompt for the switch $hostnamen"
continue
}
eof {
send_user "nSSH failure for hostname for the switch $hostnamen"
continue
}
"*-> $"
}
下图为示例。
#!/usr/bin/expect
set timeout 3
send_user "we are waiting for the word 'hi' n"
#Looping for 10 times
foreach x { 1 2 3 4 5 6 7 8 9 10} {
puts "Is anybody there???"
expect {
timeout {
puts "Nobody responding to me at trial $x"
puts "I'm waiting"
#Proceeding with the next element of the loop, using 'continue'
continue
}
#Dont bother about this 'nocase' keyword. ;)
-nocase "hi" { puts "Hey friend!" }
}
}
由于您甚至在expect
之前就产生了"clogin",因此我们在这方面是安全的,不会造成任何问题。如果它无法到达,我们将继续产生新的"clogin"。
但是,很好的做法是优雅地结束派生的过程。可以安排为
# After this command execution, the variable 'handle' will hold
# the spawn handle reference for the 'clogin' process
set handle [ spawn clogin "$hostnamer" ]
# Your expect statements here - Just modifying it for our needs
expect {
timeout {
send_user "n Failed to get login prompt for the switch $hostnamen"
# Closing the process gracefully
close $handle
continue
}
eof {
send_user "nSSH failure for hostname for the switch $hostnamen"
close $handle
continue
}
"*-> $"
}
我正在搜索类似这个脚本的内容,只是它会在三分之一的时间内执行。那么,如何获取列表,将其拆分为三个文件/部分,然后在三个不同的会话中执行更改呢。从而更快地完成。