循环提示输入另一个密码时出现问题 [英] Problems looping to prompt for another password

查看:117
本文介绍了循环提示输入另一个密码时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要有关EXPECT脚本的帮助....

I need some help with an EXPECT script please....

在尝试访问大量主机之前,我正在尝试自动进行登录,并考虑到用户输入错误密码的时间.我先获取用户名和密码,然后针对特定主机对此进行验证.如果密码无效,我想循环浏览,然后再次要求输入用户名和密码.

I'm trying to automate a login, prior to accessing a load of hosts, and cater for when a user enters a password incorrectly. I am getting the username and password first, and then validating this against a particular host. If the password is invalid, I want to loop round and ask for the username and password again.

我正在尝试:-

(省略了不相关的几行)

(preceding few irrelevant lines omitted)

    while {1} {
            send_user "login as:- "
            expect -re "(.*)\n"
            send_user "\n"
            set user $expect_out(1,string)
            stty -echo
            send_user "password: "
            expect -re "(.*)\n"
            set password $expect_out(1,string)
            stty echo

            set host "some-box.here.there.co.uk"
            set hostname "some-box"
            set host_unknown 0
            spawn ssh $user@$host
            while {1} {
                    expect {
                            "Password:"     {send $password\n
                                            break}
                            "(yes/no)?"     {send "yes\n"}
                            "Name or service not known"     {set host_unknown 1
                                                            break}
                            }
                    }
            if {$host_unknown < 1} {

                    expect {
                            "$hostname#"    {send "exit\r"
                                            break
                                            }
                            "Password:"     {send \003
                                            expect eof
                                            close $spawn_id
                                            puts "Invalid Username or Password - try again..."
                                            }
                            }
                    } elseif {$host_unknown > 0} {

                            exit 0}
            }
    puts "dropped out of loop"

现在我可以出发去做很多东西了,很多箱子.....

And now I can go off and do lots of stuff to lots of boxes .....

当我输入有效的用户名或密码,并且脚本关闭并执行我想要的所有其他操作时,此方法正常工作,但是当我输入无效的密码时,我会得到此信息:-

This works fine when I enter a valid username or password, and my script goes off and does all the other stuff I want, but when I enter an invalid password I get this :-

Fred @ Aserver:〜$ ./Ex_Test.sh全部

Fred@Aserver:~$ ./Ex_Test.sh ALL

登录为:-MyID

密码:生成ssh MyID@some-box.here.there.co.uk
密码:

password: spawn ssh MyID@some-box.here.there.co.uk
Password:

密码: 无效的用户名或密码-重试...
登录身份:-找不到名为"exp6"的频道

Password: Invalid Username or Password - try again...
login as:- cannot find channel named "exp6"

while executing  "expect -re "(.*)\n""
invoked from within  "if {[lindex $argv 1] != ""} {
    puts "Too many arguments"
    puts "Usage is:-  Ex_Test.sh  host|ALL"

} elseif {[lindex $ argv 0]!="} {

} elseif {[lindex $argv 0] != ""} {

    while {1} {
    ..."
(file "./Ex_Test.sh" line 3)

它的行找不到名为"exp6"的频道,这确实困扰着我.

Its the line "can not find channel named "exp6" which is really bugging me.

我做错了什么?我正在阅读Exploring Expect(Don Lines),但一无所获....

What am I doing wrong? I am reading Exploring Expect (Don Lines) but getting nowhere....

推荐答案

每当应该expect等待某个单词时,它会将用于该预期过程的spawn_id保存到expect_out(spawn_id)中.

Whenever expect is supposed to wait for some word, it will save the spawn_id for that expect process into expect_out(spawn_id).

根据您的代码,exp的spawn_id在遇到

As per your code, expect's spawn_id is generated when it encounters

        expect -re "(.*)\n"

当用户键入某些内容并按Enter键时,它将保存期望值的spawn_id.如果您在调试中使用了Expect,那么您可能会在调试输出中看到以下内容

When user typed something and pressed enter key, it will save the expect's spawn_id. If you have used expect with debugging, you might have seen the following in the debugging output

expect does "" (spawn_id exp0) match regular expression "(.*)\n" 

假设用户键入"Simon",则调试输出将为

Lets say user typed 'Simon', then the debugging output will be

expect: does "Simon\n" (spawn_id exp0) match regular expression "(.*)\n"? Gate "*\n"? gate=yes re=yes
expect: set expect_out(0,string) "Simon\n"
expect: set expect_out(1,string) "Simon"
expect: set expect_out(spawn_id) "exp0"
expect: set expect_out(buffer) "Simon\n"

正如您所看到的,Expect_out(spawn_id)包含要从中期望值的spawn_id.在这种情况下,术语exp0指向标准输入.

As you can see, the expect_out(spawn_id) holds the spawn_id from which it has to expect for values. In this case, the term exp0 pointing the standard input.

如果使用spawn命令,则您知道,tcl变量spawn_id保存对进程句柄的引用,该过程句柄称为派生句柄.我们可以通过显式设置进程句柄并将其保存以供将来参考来使用spawn_id.这是一个很好的部分.

If spawn command is used, then as you know, the tcl variable spawn_id holds the reference to the process handle which is known as the spawn handle. We can play around with spawn_id by explicitly setting the process handle and save it for future reference. This is one good part.

根据您的代码,当使用以下代码输入错误密码时,您将关闭ssh连接

As per your code, you are closing the ssh connection when wrong password given with the following code

close $spawn_id

通过利用spawn_id的优势,您正在执行此操作,而您所缺少的是将expect的进程句柄设置回其原始引用句柄.即

By taking advantage of spawn_id, you are doing this and what you are missing is that setting the expect's process handle back to it's original reference handle. i.e.

While {1} { 

    ###Initial state. Nothing present in spawn_id variable ######
    expect "something here"; #### Now exp0 will be created  

    ###some code here ####

    ##Spawning a process now###

    spawn ssh xyz ##At this moment, spawn_id updated

    ###doing some operations###
    ###closing ssh with some conditions###
    close $spawn_id

    ##Loop is about to end and still spawn_id has the reference to ssh process  
    ###If anything present in that, expect will assume that might be current process
    ###so, it will try to expect from that process

}

当循环第二次执行时,expect会尝试从spawn_id句柄获取命令,这只是ssh进程,这就是为什么会出现错误

When the loop executes for the 2nd time, expect will try to expect commands from the spawn_id handle which is nothing but ssh process which is why you are getting the error

can not find channel named "exp6" 

请注意,"exp6"不过是ssh进程的派生句柄.

Note that the "exp6" is nothing but the spawn handle for the ssh process.

更新:

如果 spawn_id,那么expect将始终期望来自该命令的命令 仅处理.

If some process handle is available in the spawn_id, then expect will always expect commands from that process only.

也许您可以尝试以下类似方法来避免这些情况.

Perhaps you can try something like the following to avoid these.

#Some reference variable 
set expect_init_spawn_id 0

while {1} {

    if { $expect_spawn_id !=0 } {
            #when the loop enters from 2nd iteration,
            #spawn_id is explicitly set to initial 'exp0' handle
            set spawn_id $expect_init_spawn_id 
    }

    expect -re "(.*)\n"
    #Saving the init spawn id of expect process
    #And it will have the value as 'exp0'
    set expect_init_spawn_id $expect_out(spawn_id)
    spawn ssh xyz

    ##Manipulations here

    #closing ssh now
    close $spawn_id
}

这是我的观点,可能不是有效的方法.您也可以考虑自己的逻辑来处理这些问题.

This is my opinion and it may not be the efficient approach. You can also think of your own logic to handle these problems.

这篇关于循环提示输入另一个密码时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆