期望错误处理 - spawn id 未打开
expect error handling - spawn id not open
我正在编写一个 expect 脚本,它可以在数百个路由器中注销并更改它们的配置。
我的问题是,路由器固件存在错误,导致它们在发送密码后关闭连接。
如果我再次登录,它会完美运行(因此只有重启后的第一次登录才会导致异常)。
当连接关闭时,期望脚本终止。
我希望我能优雅地捕获异常,然后重试。
失败的代码是这部分:
# go through each IP
for {set i $start} {$i <= $end} {incr i} {
set ip "10.$octet2.$i.x"
puts "\n\n\n#### doing $ip...\n" ; flush stdout
# log in to the IP
spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -l $user $ip
expect {
"continue connecting (yes/no)?" { send "yes\r" ; exp_continue }
"login as: " { send "$user\r" ; exp_continue }
"Password: " { send "$pwd\r" }
"No route to host" { continue }
timeout { continue }
}
# execute commands from file
foreach c "$commands" { eval $c }
}
我得到的错误如下所示:
Password:
Connection to 10.x.x.x closed by remote host.
Connection to 10.x.x.x closed.
send: spawn id exp11 not open
while executing
"send "exit\r""
("eval" body line 1)
invoked from within
"eval $c "
("foreach" body line 1)
invoked from within
"foreach c "$commands" { eval $c }"
("for" body line 18)
invoked from within
"for {set i $start} {$i <= $end} {incr i} {
set ip "10.$octet2.$i.x"
puts "\n\n\n#### doing $ip...\n" ; flush stdout
# log in to the IP
spa..."
(file "./multido.exp" line 39)
非常感谢任何帮助!
您可以使用 tcl 命令捕获异常 catch
包围可能出错的命令。您可以将代码的内部循环扩展为如下所示:
set tryrun 1
while {$tryrun} {
spawn ssh ...
expect ...
set tryrun 0
foreach c "$commands" {
if {[catch {eval $c} result]} {
puts "failed: $result"
set tryrun 1
}
}
}
也许更简单的解决方案是在您的期望中寻找模式 "closed by remote host"
,并使用它来重复类似的循环。
我正在编写一个 expect 脚本,它可以在数百个路由器中注销并更改它们的配置。
我的问题是,路由器固件存在错误,导致它们在发送密码后关闭连接。 如果我再次登录,它会完美运行(因此只有重启后的第一次登录才会导致异常)。 当连接关闭时,期望脚本终止。
我希望我能优雅地捕获异常,然后重试。
失败的代码是这部分:
# go through each IP
for {set i $start} {$i <= $end} {incr i} {
set ip "10.$octet2.$i.x"
puts "\n\n\n#### doing $ip...\n" ; flush stdout
# log in to the IP
spawn ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -l $user $ip
expect {
"continue connecting (yes/no)?" { send "yes\r" ; exp_continue }
"login as: " { send "$user\r" ; exp_continue }
"Password: " { send "$pwd\r" }
"No route to host" { continue }
timeout { continue }
}
# execute commands from file
foreach c "$commands" { eval $c }
}
我得到的错误如下所示:
Password:
Connection to 10.x.x.x closed by remote host.
Connection to 10.x.x.x closed.
send: spawn id exp11 not open
while executing
"send "exit\r""
("eval" body line 1)
invoked from within
"eval $c "
("foreach" body line 1)
invoked from within
"foreach c "$commands" { eval $c }"
("for" body line 18)
invoked from within
"for {set i $start} {$i <= $end} {incr i} {
set ip "10.$octet2.$i.x"
puts "\n\n\n#### doing $ip...\n" ; flush stdout
# log in to the IP
spa..."
(file "./multido.exp" line 39)
非常感谢任何帮助!
您可以使用 tcl 命令捕获异常 catch
包围可能出错的命令。您可以将代码的内部循环扩展为如下所示:
set tryrun 1
while {$tryrun} {
spawn ssh ...
expect ...
set tryrun 0
foreach c "$commands" {
if {[catch {eval $c} result]} {
puts "failed: $result"
set tryrun 1
}
}
}
也许更简单的解决方案是在您的期望中寻找模式 "closed by remote host"
,并使用它来重复类似的循环。