考虑这样的场景:
#start of the script
proc A {host_ip} {
spawn ssh $host_ip
#possibly 1 to n expect statements to pattern
#match on the output of the spawned process
}
proc B {} {
#pattern match using expect statements on the
#output of the spawned process in A
}
proc C {} {
#pattern match using expect statements on the
#output of the spawned process in A
}
#call the proc's
A $some_IP
B
C
#pattern match here, not part of a procedure,
#but an expect statement to match output of
#the spawned process in A
#end of the script
从Expect/Tcl在线文档来看,我有两个选项:
返回A中生成进程的PID,然后在A之外的expect语句中显式地使用它,使用expect语句形式:
expect -i $PID_FROM_A ...
似乎有一些魔法/全局变量,如果它的值被设置为A中生成进程的PID,那么脚本中的所有expect语句都可以在A中生成进程的输出上进行模式匹配。
1将工作,我没有测试,但文档对此非常清楚。我更喜欢2,因为我不想在脚本中显式地传递PID给每个expect语句,但我不知道要覆盖哪个全局变量(如果有的话)。任何帮助都是感激的。谢谢。
这个神奇变量叫做spawn_id
。您必须将global spawn_id
放在调用spawn
的过程中(在spawn
之前),否则可以不声明它。这是因为当Expect 读取变量时,它不仅仅搜索当前作用域,但是当它写入变量时,它只写入当前作用域(这是而不是正常的Tcl行为;Tcl通常只从当前作用域读取和写入,除非另有明确指示)。来自Expect手册:
因此,您所需要做的就是将Expect对作用域的看法比较自由。特别是,由Expect程序的命令读取的变量将首先从局部作用域查找,如果没有找到,则在全局作用域中查找。例如,这避免了在编写使用
expect
的每个过程中放置"global timeout
"的需要。另一方面,写入的变量总是在局部作用域中(除非发出了"global
"命令)。最常见的问题是在过程中执行spawn
时。在过程之外,spawn_id
不再存在,因此生成的进程不再仅仅因为作用域而被访问。在这样的过程中添加一个"global spawn_id
"。
A
更改为:
proc A {host_ip} {
global spawn_id
spawn ssh $host_ip
#possibly 1 to n expect statements to pattern
#match on the output of the spawned process
}