0

我有一个期望脚本:

expect - "$@" << 'END_OF_FILE'
        set username [lindex $argv 0]
        set hosts [lindex $argv 1]
        set Passwordfile [lindex $argv 2 ]
        set Commands "[lindex $argv 3 ];\r"
        set prompt [lindex $argv 4 ]
#        log_user 0
#exp_internal 1
        if { [llength $argv] != 5} {
             puts "usage: username hostname password commands prompt"
             exit 1
         }


        set force_conservative 0  ;# set to 1 to force conservative mode even if
                                  ;# script wasn't run conservatively originally
        if {$force_conservative} {
                set send_slow {1 .1}
                proc send {ignore arg} {
                        sleep .1
                        exp_send -s -- $arg
                }
        }
#
#COMMENTS
#SendCommands function sends the all the commands passed to it.All the commands passed to it must be separated by a semicolon and put a \r at last

set pfile [ open "$Passwordfile" "r"]

        proc SendCommands { Commands } {
        global prompt log errlog
            foreach element [split $Commands ";"] {
                    expect {
                           -re $prompt
                        {send -- "$element\r"}
                                       } 

               }

        }

        set timeout 20

        foreach  host [ split $hosts "\;" ] {
        spawn ssh -o "StrictHostKeyChecking no" "$username@$host" 
        match_max   1000000
        set expect_out(buffer) {}

        expect {
          timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
          eof { send_user "\nSSH failure for $host\n"; exit 1 }
               "*?assword:*"
              {
               send -- "[read $pfile]\r"
               seek $pfile 0 start
              }

        }


        expect {
                  timeout { send_user "\nLogin incorrect\n"; exit 1 }
                  eof { send_user "\nSSH failure for $host\n"; exit 1 }

             -re  "$prompt"
               { send -- "\r" }
               }
        set timeout 60
        close "$pfile"
    SendCommands "$Commands"
    }

END_OF_FILE

我可以像这样执行它:

./scriptname username hostname passwordfile "commnmad1;commnad2;command3" "(.*#|.*>)$"

但如果我通过执行enable命令更改模式,我将得到密码提示而不是通常的提示(# 或 >)。enable如果命令是或我收到密码提示,我如何确保执行以下代码。

        expect {
          timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
          eof { send_user "\nSSH failure for $host\n"; exit 1 }
               "*?assword:*"
              {
               send -- "[read $pfile]\r"
               seek $pfile 0 start
              }

        }
4

1 回答 1

2

你可能想要

expect {
    timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
    eof     { send_user "\nSSH failure for $host\n"; exit 1 }
    "*?assword:*" {
           send -- "[read -nonewline $pfile]\r"
           seek $pfile 0 start
           exp_continue
    }
    $prompt
}

我将-nonewline选项添加到读取命令。当您发送密码时,exp_continue您将一直处于这个预期的“循环”中,直到满足其他条件之一,包括提示。

于 2013-06-21T16:10:10.033 回答