2013-03-20 95 views
0

首先我需要说我使用公钥和私钥,但这并没有解决我的问题。另外我知道我可以使用两个脚本(一个使用password1,另一个使用password2)并运行它们两次,但我想知道为什么下面的脚本不起作用。我试图让期望的脚本,将通过SSH连接,并检查两个密码之一是否正确。对于这个我检查脚本的退出代码:expect - ssh - 两个可能的密码 - 或者如何跳过expect块并仍然使用发送clausule

可以有远程机器上更可能的登录提示,我想使这个脚本尽可能通用,所以我不能依靠登录提示字符串。到目前为止,我有这样的代码:

#!/usr/local/bin/expect 
set username "username"; 
set remote_server "machine"; 
set password1 "badpassword"; 
set password2 "goodpassword"; 

set timeout 5; 
set pretype 0; 
set retcode 0; 


if { $pretype == 0 } { 
    spawn ssh -q ${username}@${remote_server} 
    expect { 
    "no)?" { send "yes\r"; } 
    "denied" { 
       puts "Can't login to $remote_server. Check username and password\n"; 
       set retcode 2; 
      } 
    "telnet:" { 
       puts "Can't connect to $remote_server via SSH or Telnet. Something went definitely wrong\n"; 
       set retcode 3; 
       } 
    "failed" { 
       puts "Host $remote_server exists. Check ssh_hosts file\n"; 
       set retcode 4; 
      } 
    timeout { 
       puts "Timeout problem. Host $remote_server doesn't respond\n"; 
       set retcode 5; 
      } 
    "refused" { 
       puts "Host $remote_server refused to SSH. That is insecure.\n"; 
       set retcode 6; 
       } 
    "assword:" { set pretype 1; send "${password1}\r"; } 
    } 
} else { 
    expect{ 
     "assword:" { send "${password2}\r"; exit 1; } 
     timeout { exit 0; } 
    } 
} 

这背后的想法是:若我输入密码错误,我将必须键入正确的第二次机会。所以,如果我第一次输入错误的密码,我的脚本应该继续在其他分支(因为我set pretype to 1)。在这里,我会等待再次输入密码。所以我会发送第二个密码并退出代码1(密码2是OK)。如果其他分支中的超时过期(“password:”字符串不匹配),最有可能我已经有登录提示,所以脚本将退出代码0(密码1是OK)。但是这并没有工作,如果我跑这里面调试器,我看到的最后一行是:

send: sending "badpassword\r\r" to { exp4 } 

我不知道为什么会这样,但似乎从来没有剧本到达else分支。非常感谢

回答

1

set pretype 1if块中不能使它再次进入else块。没有编程语言会这样做。你需要像循环(使用whileexp_continue)这里。

下面是一个例子:

#!/usr/bin/expect 

set passwords { bad1 bad2 bad3 good } 

spawn ssh -o PreferredAuthentications=keyboard-interactive \ 
      -o NumberOfPasswordPrompts=[llength $passwords] [email protected] 

set try 0 
expect { 
    "Password: " { 
     if { $try >= [llength $passwords] } { 
      send_error ">>> wrong passwords\n" 
      exit 1 
     } 

     send [lindex $passwords $try]\r 
     incr try 
     exp_continue 
    } 

    "bash-4.2" { 
     interact 
    } 

    timeout { 
     send_error ">>> timed out\n" 
     exit 1 
    } 
}