Bash Expect-找不到名为“Expect”的频道&引用;执行时

Bash Expect-找不到名为“Expect”的频道&引用;执行时,bash,if-statement,ssh,error-handling,expect,Bash,If Statement,Ssh,Error Handling,Expect,尝试从单个expect脚本中生成一个SSH会话到一个或多个分支位置设备 我有一个bash脚本,它包含3个参数: Expect脚本 expect脚本结果的输出目录 我要连接到的分支位置列表 所有设备都映射到DNS节点,因此站点1234将有1-5个我想要的设备。 比如说1234R、1234FW1、1234S1和/或1234S2 站点列表是从传递给bash包装器的文件中提取的。 站点号将从此文件传递给expect脚本 expect脚本有5个列表对象和5个if语句。 如果列表不为空,请处理列表中的命令。

尝试从单个expect脚本中生成一个SSH会话到一个或多个分支位置设备

我有一个bash脚本,它包含3个参数:

  • Expect脚本
  • expect脚本结果的输出目录
  • 我要连接到的分支位置列表
  • 所有设备都映射到DNS节点,因此站点1234将有1-5个我想要的设备。 比如说1234R、1234FW1、1234S1和/或1234S2

    站点列表是从传递给bash包装器的文件中提取的。 站点号将从此文件传递给expect脚本

    expect脚本有5个列表对象和5个if语句。 如果列表不为空,请处理列表中的命令。 每个列表都对应于我要在分支位置连接到的设备类型(它们必须不同,因为CLI提示符不同,我们不希望意外地在无意中运行的设备上运行命令)

    我的问题是,如果我的expect脚本无法处理设备2/5,比如说因为无法访问/脱机,它将停止处理其余的设备

    所以,如果对于站点1234,我想处理设备2/5(FW1)和设备4/5(S1)上的命令,但FW1处于脱机状态,S1永远不会被处理

    我无法退出,因为这将退出整个脚本。 我尝试使用expect eof、close-I$spawn\u id来关闭全局spawn\u id,甚至还有一个超时,但是这个过程每次都会给我相同的错误。我觉得我错过了一些非常明显的东西

    以下是Expect脚本:

    #!/usr/bin/expect
    
    #Purpose: SSH to remote juniper hosts and execute commands.
    #Syntax: <script name> <site number> <username> <password>
    
    global spawn_id;
    global sess_id;
    
    
    set cmds_R [ list \
    
    ]
    
    
    set cmds_FW1 [ list \
    "show system license" \
    "exit" \
    ]
    
    
    set cmds_10MB [ list \
    
    ]
    
    
    set cmds_S1 [ list \
    "show interfaces terse | no-more" \
    "exit" \
    ]
    
    
    set cmds_S2 [ list \
    
    ]
    
    
    
    
    
    
    
    
    
    
    
    
    
    # Check for Primary Router commands
    # If found, run Primary router commands.
    
    if { $cmds_R != "" } {
      proc _jgetRouterIPs {} {
      set file [open router-list r]
    
    while {![eof $file]} {
      set buff [read $file]
    }
    close $file
    return $buff
    }
    
    
    
    proc ssh2rtr { rtr usr pwd } {
        spawn ssh -l $usr $rtr;
        set sess_id $spawn_id;
        set ppret [ processPrompts $rtr $usr $pwd $sess_id 0 ];
        set timeout 60;
    if { $ppret == 0 } { 
        return $spawn_id; 
    } else { 
        send_user "Failed to process prompts on R!!!";
      }
    }
    
    
    proc processPrompts { rtr usr pwd sess_id status } {
          set timeout 90;
          set spawn_id $sess_id;
          set fw_prompt  {\n*@[0-9]{4}\-[A-Z]{2}\-R(>|#)\s};
    
    if { $status < 2 } {
          expect {
          -re  $fw_prompt { return 0;}
    
          "no)?" {  send "yes\r";
           processPrompts $rtr $usr $pwd $sess_id 0;
            }
    
    
          "assword:" {
                    send "${pwd}\r";
           if { $status} { return 1;}
           processPrompts $rtr $usr $pwd $sess_id 1;
            }
    
          "ssh: Could not resolve hostname" {
              send_user "\nDNS Error!!! Check Hostname and try again!\n"; return 10;
          }
    
    
         timeout     { send_user "\nTimeout on SSH!!!\n"; return 8;}  ;#no reponse from telnet/ssh
         default     { send_user "\nSSH Unknown Error!!!\n"; return 9;} ;#unknown error has occurred.
    } ;#end expect
    } ;#end if
    }
    
    
    set site [lindex $argv 0];
    set fw "${site}R";
    set usr [lindex $argv 1];
    set pwd [lindex $argv 2];
    set fw_prompt  {\n*@[0-9]{4}\-[A-Z]{2}\-R(>|#)\s};
    set yesorp {(\(yes\))|(-R(>|#))};
    
    
    set timeout 90;
    set sshret  [ ssh2rtr $fw $usr $pwd ] ;
    if { $sshret != 99 } {
        set spawn_id $sshret;
    } else {
        send_user "Error Connecting...!!!";
    }
    
    foreach cmd $cmds_R {
    send "${cmd}\r";
    expect -re $fw_prompt;
    }
    
    } else {
      send_user "\nNo commands for Router\n";
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    # Check for Backup Router commands
    # If found, run Backup router commands.
    
    
    if { $cmds_FW1 != "" } {
    proc _jgetRouterIPs {} {
      set file [open router-list r]
    
    while {![eof $file]} {
      set buff [read $file]
    }
    close $file
    return $buff
    }
    
    
    
    proc ssh2rtr { rtr usr pwd } {
        spawn ssh -l $usr $rtr;
        set sess_id $spawn_id;
        set ppret [ processPrompts $rtr $usr $pwd $sess_id 0 ];
        set timeout 60;
    if { $ppret == 0 } { 
        return $spawn_id; 
    } else { 
        send_user "Failed to process prompts on FW1!!!"; 
      }
    }
    
    
    proc processPrompts { rtr usr pwd sess_id status } {
          set timeout 90;
          set spawn_id $sess_id;
          set fw_prompt  {\n*@[0-9]{4}\-[A-Z]{2}\-FW1(>|#)\s};
    
    if { $status < 2 } {
          expect {
          -re  $fw_prompt { return 0;}
    
          "no)?" {  send "yes\r";
           processPrompts $rtr $usr $pwd $sess_id 0;
            }
    
    
          "assword:" {
                    send "${pwd}\r";
           if { $status} { return 1;}
           processPrompts $rtr $usr $pwd $sess_id 1;
            }
    
          "ssh: Could not resolve hostname" {
              send_user "\nDNS Error!!! Check Hostname and try again!\n"; return 10;
          }
    
    
         timeout     { send_user "\nTimeout on SSH!!!\n"; return 8;}  ;#no reponse from telnet/ssh
         default     { send_user "\nSSH Unknown Error!!!\n"; return 9;} ;#unknown error has occurred.
    } ;#end expect
    } ;#end if
    }
    
    
    set site [lindex $argv 0];
    set fw "${site}FW1";
    set usr [lindex $argv 1];
    set pwd [lindex $argv 2];
    set fw_prompt  {\n*@[0-9]{4}\-[A-Z]{2}\-FW1(>|#)\s};
    set yesorp {(\(yes\))|(-FW1(>|#))};
    
    
    set timeout 90;
    set sshret  [ ssh2rtr $fw $usr $pwd ] ;
    if { $sshret != 99 } {
        set spawn_id $sshret;
    } else {
        send_user "Error Connecting...!!!";
    }
    
    
    foreach cmd $cmds_FW1 {
    send "${cmd}\r";
    expect -re $fw_prompt;
    }
    
    
    } else {
      send_user "\nNo commands for Backup FW1\n";
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    # Check for 10MB Router commands
    # If found, run 10MB Router commands.
    
    if { $cmds_10MB != "" } {
    proc _jgetRouterIPs {} {
      set file [open router-list r]
    
    while {![eof $file]} {
      set buff [read $file]
    }
    close $file
    return $buff
    }
    
    
    
    proc ssh2rtr { rtr usr pwd } {
        spawn ssh -l $usr $rtr;
        set sess_id $spawn_id;
        set ppret [ processPrompts $rtr $usr $pwd $sess_id 0 ];
    
    if { $ppret == 0 } { 
        return $spawn_id; 
    } else { 
        send_user "Failed to process prompts on 10MB!!!";
        close;
        close -i $spawn_id;
      }
    }
    
    
    proc processPrompts { rtr usr pwd sess_id status } {
          set timeout 90;
          set spawn_id $sess_id;
          set fw_prompt  {[a-z0-9]+@+[0-9]+([A-Za-z0-9-]{5,11})(>|#)};
    
    if { $status < 2 } {
          expect {
          -re  $fw_prompt { return 0;}
    
          "no)?" {  send "yes\r";
           processPrompts $rtr $usr $pwd $sess_id 0;
            }
    
    
          "assword:" {
                    send "${pwd}\r";
           if { $status} { return 1;}
           processPrompts $rtr $usr $pwd $sess_id 1;
            }
    
          "ssh: Could not resolve hostname" {
              send_user "\nDNS Error!!! Check Hostname and try again!\n"; return 10;
          }
    
    
         timeout     { send_user "\nTimeout on SSH!!!\n"; return 8;}  ;#no reponse from telnet/ssh
         default     { send_user "\nSSH Unknown Error!!!\n"; return 9;} ;#unknown error has occurred.
    } ;#end expect
    } ;#end if
    }
    
    
    set site [lindex $argv 0];
    set fw "${site}R";
    set usr [lindex $argv 1];
    set pwd [lindex $argv 2];
    set fw_prompt  {[a-z0-9]+@+[0-9]+([A-Za-z0-9-]{5,11})(>|#)};
    set yesorp {(\(yes\))|([A-Za-z0-9-]{5,11})(>|#)};
    
    
    set timeout 90;
    set sshret  [ ssh2rtr $fw $usr $pwd ] ;
    if { $sshret != 99 } {
        set spawn_id $sshret;
    } else {
        send_user "Error Connecting...!!!";
    }
    
    
    foreach cmd $cmds_10MB {
    send "${cmd}\r";
    expect -re $fw_prompt;
    }
    
    
    } else {
      send_user "\nNo commands for 10MB Router\n";
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    # Check for Switch 1 commands
    # If found, run Switch 1 commands.
    
    if { $cmds_S1 != "" } {
    proc _jgetRouterIPs {} {
      set file [open router-list r]
    
    while {![eof $file]} {
      set buff [read $file]
    }
    close $file
    return $buff
    }
    
    
    
    proc ssh2rtr { rtr usr pwd } {
        spawn ssh -l $usr $rtr;
        set sess_id $spawn_id;
        set ppret [ processPrompts $rtr $usr $pwd $sess_id 0 ];
    
    if { $ppret == 0 } { 
        return $spawn_id; 
    } else { 
        send_user "Failed to process prompts on S1!!!";
        close;
        close -i $spawn_id;
      }
    }
    
    
    proc processPrompts { rtr usr pwd sess_id status } {
          set timeout 90;
          set spawn_id $sess_id;
          set fw_prompt  {\n*@[0-9]{4}\-[A-Z]{2}\-S1(>|#)\s};
    
    if { $status < 2 } {
          expect {
          -re  $fw_prompt { return 0;}
    
          "no)?" {  send "yes\r";
           processPrompts $rtr $usr $pwd $sess_id 0;
            }
    
    
          "assword:" {
                    send "${pwd}\r";
           if { $status} { return 1;}
           processPrompts $rtr $usr $pwd $sess_id 1;
            }
    
          "ssh: Could not resolve hostname" {
              send_user "\nDNS Error!!! Check Hostname and try again!\n"; return 10;
          }
    
    
         timeout     { send_user "\nTimeout on SSH!!!\n"; return 8;}  ;#no reponse from telnet/ssh
         default     { send_user "\nSSH Unknown Error!!!\n"; return 9;} ;#unknown error has occurred.
    } ;#end expect
    } ;#end if
    }
    
    
    set site [lindex $argv 0];
    set fw "${site}S1";
    set usr [lindex $argv 1];
    set pwd [lindex $argv 2];
    set fw_prompt  {\n*@[0-9]{4}\-[A-Z]{2}\-S1(>|#)\s};
    set yesorp {(\(yes\))|(-S1(>|#))};
    
    
    set timeout 90;
    set sshret  [ ssh2rtr $fw $usr $pwd ] ;
    if { $sshret != 99 } {
        set spawn_id $sshret;
    } else {
        send_user "Error Connecting...!!!";
    }
    
    
    foreach cmd $cmds_S1 {
    send "${cmd}\r";
    expect -re $fw_prompt;
    }
    
    
    } else {
      send_user "\nNo commands for Switch 1\n";
    }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    # Check for Switch 2 commands
    # If found, run Switch 2 commands.
    
    if { $cmds_S2 != "" } {
    proc _jgetRouterIPs {} {
      set file [open router-list r]
    
    while {![eof $file]} {
      set buff [read $file]
    }
    close $file
    return $buff
    }
    
    
    
    proc ssh2rtr { rtr usr pwd } {
        spawn ssh -l $usr $rtr;
        set sess_id $spawn_id;
        set ppret [ processPrompts $rtr $usr $pwd $sess_id 0 ];
    
    if { $ppret == 0 } { 
        return $spawn_id; 
    } else { 
        send_user "Failed to process prompts on S2!!!";
        close;
        close -i $spawn_id;
      }
    }
    
    
    proc processPrompts { rtr usr pwd sess_id status } {
          set timeout 90;
          set spawn_id $sess_id;
          set fw_prompt  {\n*@[0-9]{4}\-[A-Z]{2}\-S2(>|#)\s};
    
    if { $status < 2 } {
          expect {
          -re  $fw_prompt { return 0;}
    
          "no)?" {  send "yes\r";
           processPrompts $rtr $usr $pwd $sess_id 0;
            }
    
    
          "assword:" {
                    send "${pwd}\r";
           if { $status} { return 1;}
           processPrompts $rtr $usr $pwd $sess_id 1;
            }
    
          "ssh: Could not resolve hostname" {
              send_user "\nDNS Error!!! Check Hostname and try again!\n"; return 10;
          }
    
    
         timeout     { send_user "\nTimeout on SSH!!!\n"; return 8;}  ;#no reponse from telnet/ssh
         default     { send_user "\nSSH Unknown Error!!!\n"; return 9;} ;#unknown error has occurred.
    } ;#end expect
    } ;#end if
    }
    
    
    set site [lindex $argv 0];
    set fw "${site}S2";
    set usr [lindex $argv 1];
    set pwd [lindex $argv 2];
    set fw_prompt  {\n*@[0-9]{4}\-[A-Z]{2}\-S2(>|#)\s};
    set yesorp {(\(yes\))|(-S2(>|#))};
    
    
    set timeout 90;
    set sshret  [ ssh2rtr $fw $usr $pwd ] ;
    if { $sshret != 99 } {
        set spawn_id $sshret;
    } else {
        send_user "Error Connecting...!!!";
    }
    
    
    foreach cmd $cmds_S2 {
    send "${cmd}\r";
    expect -re $fw_prompt;
    }
    
    
    } else {
      send_user "\nNo commands for Switch 2\n";
    }
    
    我想更干净地处理这个问题,并通过send_user输出一条消息,表示无法处理提示,然后继续,直到所有5条if语句都已测试并完成

    目前,它将执行else子句中的send_user,但我在那里添加的任何其他内容都不允许我继续执行第一个if/else语句。脚本刚刚退出

      if { $ppret == 0 } { 
            return $spawn_id; 
        } else { 
            send_user "Failed to process prompts on R!!!";
          }
        }
    

    在tcl中,
    global
    如果不在进程中则无效。您发布的scrpit有点太长。别人读起来不容易。您可以
    expect-d/your/script.exp
    查看详细情况。您的
    processPrompts
    并不总是返回值。e、 例如,
    processPrompts$rtr$usr$pwd$sess_id 0
    应该是
    return[processPrompts$rtr$usr$pwd$sess_id 0]
    ?期望陌生人为您调试程序太过分了。确保您了解expect如何进行变量作用域(请参阅expect手册页的“注意事项”部分)。在tcl中,
    global
    如果不在进程中,则没有任何效果。您发布的scrpit有点太长。别人读起来不容易。您可以
    expect-d/your/script.exp
    查看详细情况。您的
    processPrompts
    并不总是返回值。e、 例如,
    processPrompts$rtr$usr$pwd$sess_id 0
    应该是
    return[processPrompts$rtr$usr$pwd$sess_id 0]
    ?期望陌生人为您调试程序太过分了。确保您了解expect如何进行变量作用域(请参阅expect手册页的“注意事项”部分)。
      if { $ppret == 0 } { 
            return $spawn_id; 
        } else { 
            send_user "Failed to process prompts on R!!!";
          }
        }