每当expect
应该等待一些词,它会保存spawn_id
对于那个期望过程expect_out(spawn_id)
.
根据您的代码,expect的spawn_id是在遇到时生成的
expect -re "(.*)\n"
当用户输入内容并按下回车键时,它将保存expect的spawn_id。如果您在调试中使用了expect,您可能会在调试输出中看到以下内容
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
指向标准输入。
If spawn
使用命令,然后如您所知,tcl 变量spawn_id
保存对进程句柄的引用,称为生成句柄。我们可以玩玩spawn_id
通过显式设置进程句柄并将其保存以供将来参考。这是一个很好的部分。
根据您的代码,当使用以下代码给出错误密码时,您将关闭 ssh 连接
close $spawn_id
通过利用spawn_id
,你正在这样做,而你缺少的是设置expect
的进程句柄返回到其原始参考句柄。 IE。
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 进程,这就是您收到错误的原因
can not find channel named "exp6"
请注意,“exp6”只不过是 ssh 进程的生成句柄。
Update :
如果某个进程句柄可用spawn_id
, then 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
}
这是我的观点,可能不是有效的方法。你也可以想出自己的逻辑来处理这些问题。