【问题标题】:Multiple Spawn/expect issue多重产卵/预期问题
【发布时间】:2021-02-16 15:39:29
【问题描述】:

目前,我正在编写一个脚本来自动化数据收集器流程。通过长期运行,我将这些收集器脚本分成四部分。现在我想同时启动这些 Collectorscripts,但我不知道该怎么做。我的代码有点工作:

package require Expect
log_user 0
set timeout 10200

spawn ./Log.tcl 2 5 1; set spawn1 $spawn_id
spawn ./Log.tcl 3 4 2; set spawn2 $spawn_id
spawn ./Log.tcl 7 8 2; set spawn3 $spawn_id
spawn ./Log.tcl 6 9 3; set spawn4 $spawn_id
expect -i $spawn1 eof {wait ; puts "--- 2,5 fertig ---"}
expect -i $spawn2 eof {wait ; puts "--- 3,4 fertig ---"}
expect -i $spawn3 eof {wait ; puts "--- 7,8 fertig ---"}
expect -i $spawn4 eof {puts "--- 6,9 fertig ---"}

这是运行并制作的东西。但是,如果一项工作在另一项之前准备好,它将产生僵尸。有没有可能让这变得简单而美丽?我用 exp_after、exp_background、$any_spawn_id 和 while 循环尝试了一些想法。但没有任何效果。期望永远不会得到 eof。

【问题讨论】:

    标签: tcl expect


    【解决方案1】:

    如果您需要知道生成的命令完成的顺序,则很难使用等待,但expect 将接受生成的 id 列表以同时收听。例如,

    spawn sleep 2
     lappend allids $spawn_id
     set cmd($spawn_id) "sleep 2"
    spawn sleep 1
     lappend allids $spawn_id
     set cmd($spawn_id) "sleep 1"
    
    while { [llength $allids]>0 } {
     expect -i "$allids" eof {
      puts "eof on $expect_out(spawn_id) from cmd $cmd($expect_out(spawn_id))"
      set idx [lsearch -exact $allids $expect_out(spawn_id)]
      set allids [lreplace $allids $idx $idx]
     }
    }
    

    这会运行 2 个命令,sleep 2sleep 1,并将每个生成 id 附加到列表 allids。为方便起见,该命令还在数组cmd 中注明,该数组由该命令的生成ID 索引。

    然后使用-i 将所有生成ID 的列表提供给expect eof。 当 eof 匹配时,全局变量 $expect_out(spawn_id) 包含导致匹配的进程的生成 id。在 cmd 数组中索引此值后会打印一条消息。

    最后,从列表中移除带有 eof 的 spawn id,并重复循环直到列表为空。

    请注意,您不能使用 exp_continue 继续期望循环,因为 -i 的值似乎没有被重新评估。

    【讨论】:

    • 感谢您的回答。您的代码运行良好。最重要的是你的笔记。我之前不知道 exp_continue 没有评估 spawn
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多