Tcl 循环提示输入另一个密码时出现问题

Tcl 循环提示输入另一个密码时出现问题,tcl,expect,Tcl,Expect,我需要一些关于EXPECT脚本的帮助 我正在尝试在访问大量主机之前自动登录,并在用户错误输入密码时提供服务。我首先获取用户名和密码,然后针对特定主机进行验证。如果密码无效,我想循环并再次询问用户名和密码 我正在尝试:- (省略前面几行不相关的内容) }elseif{[lindex$argv 0]!=“”{ 它的行“找不到名为“exp6”的频道”,这是真正困扰我 我做错了什么?我正在阅读Exploring Expect(Don line),但却一事无成。每当Expect应该等待某个单词时,它会将该

我需要一些关于EXPECT脚本的帮助

我正在尝试在访问大量主机之前自动登录,并在用户错误输入密码时提供服务。我首先获取用户名和密码,然后针对特定主机进行验证。如果密码无效,我想循环并再次询问用户名和密码

我正在尝试:-

(省略前面几行不相关的内容)

}elseif{[lindex$argv 0]!=“”{

它的行“找不到名为“exp6”的频道”,这是真正困扰我


我做错了什么?我正在阅读Exploring Expect(Don line),但却一事无成。

每当
Expect
应该等待某个单词时,它会将该Expect进程的
spawn\u id
保存到
Expect\u out(spawn\u id)

根据您的代码,expect的spawn_id是在遇到

        expect -re "(.*)\n"
当用户键入某个内容并按enter键时,它将保存expect的生成id

expect does "" (spawn_id exp0) match regular expression "(.*)\n" 
假设用户输入了“Simon”,那么调试输出将是

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
指向标准输入

如果使用了
spawn
命令,那么正如您所知,tcl变量
spawn_id
保存对进程句柄的引用,该进程句柄称为spawn句柄。我们可以通过显式设置进程句柄并将其保存以备将来参考来处理
spawn_id
,这是一个很好的部分

根据您的代码,当以下代码给出错误密码时,您正在关闭ssh连接

close $spawn_id
通过利用
spawn\u id
,您正在这样做,您缺少的是将
expect
的进程句柄设置回其原始引用句柄

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\u id
句柄中执行命令,该句柄只不过是ssh进程,这就是您出现错误的原因

can not find channel named "exp6" 
请注意,“exp6”只是ssh进程的spawn句柄

更新:

如果某个进程句柄在
spawn\u id
,则
expect
将始终期待来自该站点的命令 只处理

也许您可以尝试以下方法来避免这些问题

#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
}

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

太棒了!非常清楚的解释,现在一切都有意义了。问题解决了,我可以继续。非常感谢。
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
can not find channel named "exp6" 
#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
}