考虑排序场景:
#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在线文档看来,我有2个选项:
在A中返回生成进程的PID,然后使用expect语句形式在A之外的expect语句中显式使用它:
expect -i $PID_FROM_A ...
似乎有一些魔术/全局变量,如果其值设置为A中生成的进程的PID,则脚本中的所有expect语句都可以在A中生成的进程的输出上进行模式匹配。
1将起作用,我还没有测试过,但文档对此非常清楚。我更喜欢2,因为我不想通过显式将PID传递给每个expect语句而乱丢脚本,但我不知道要覆盖哪个全局变量(如果有的话)。任何帮助表示赞赏。感谢。
答案 0 :(得分:4)
魔术变量称为spawn_id
。您必须将global spawn_id
放入调用spawn
(在spawn
之前)的过程中,否则可以将其保留为未声明。这是因为当Expect 读取变量时,它会搜索的不仅仅是当前作用域,但是当它写入变量时,它只会写入当前作用域(这是不正常的Tcl行为; Tcl通常只读取和写入当前作用域,除非另有明确说明)。来自Expect manual:
期待对范围界定采取相当自由的观点。特别是,将首先从本地范围寻找特定于 Expect 程序的命令读取的变量,如果未找到,则在全局范围内查找。例如,这消除了放置"
global timeout
"在您编写的每个使用expect
的过程中。另一方面,写入的变量总是在本地范围内(除非已发出"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
}