脚本模式中跨过程的所有expect语句都与特定过程中唯一生成的进程产生的输出相匹配



考虑这样的场景:

    #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在线文档来看,我有两个选项:

  1. 返回A中生成进程的PID,然后在A之外的expect语句中显式地使用它,使用expect语句形式:

    expect -i $PID_FROM_A ... 
    
  2. 似乎有一些魔法/全局变量,如果它的值被设置为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
}

最新更新