代码之家  ›  专栏  ›  技术社区  ›  Niva

预期错误处理-生成id未打开

  •  0
  • Niva  · 技术社区  · 7 年前

    我正在编写一个expect脚本,它可以注销数百个路由器并更改其配置。

    我的问题是,路由器固件上有一个bug,导致它们在发送密码后关闭连接。 如果我再次登录,它可以正常工作(因此只有在重新启动后第一次登录才会导致异常)。 当连接关闭时,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 回复  |  直到 7 年前
        1
  •  0
  •   meuh    7 年前

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