期待错误处理 - spawn id未打开

时间:2018-03-02 09:05:09

标签: linux ssh error-handling 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)

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

您可以使用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",并使用它来重复类似的循环。