【问题标题】:expect - ssh - two possible passwords - or how to jump of expect block and still use send clausule期望 - ssh - 两个可能的密码 - 或者如何跳转期望块并仍然使用发送子句
【发布时间】:2013-03-21 10:09:50
【问题描述】:

首先我需要说我很喜欢使用公钥和私钥,但这并没有解决我的问题。另外我知道我可以使用两个脚本(一个使用密码 1,第二个使用密码 2)并运行它们两次,但我想知道为什么以下操作不起作用。我正在尝试制作将通过 ssh 连接并检查两个密码之一是否正确的期望脚本。为此,我正在检查脚本的退出代码:

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

#!/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; }
    }
}

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

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

我不知道为什么会发生这种情况,但似乎脚本永远不会到达 else 分支。非常感谢

【问题讨论】:

    标签: ssh expect if-statement


    【解决方案1】:

    if 块中的set pretype 1 无法使其再次进入else 块。没有编程语言会这样做。你需要类似 loop 的东西(使用whileexp_continue)。

    以下是一个例子:

    #!/usr/bin/expect
    
    set passwords { bad1 bad2 bad3 good }
    
    spawn ssh -o PreferredAuthentications=keyboard-interactive \
              -o NumberOfPasswordPrompts=[llength $passwords] root@tree
    
    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
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      • 2010-10-02
      • 1970-01-01
      • 2010-11-05
      • 1970-01-01
      • 1970-01-01
      • 2020-03-08
      相关资源
      最近更新 更多