多个 Spawn/expect 问题
Multiple Spawn/expect issue
目前,我正在编写一个脚本来自动化数据收集器进程。通过长期 运行 我将这些 Collector 脚本分成了四个部分。现在我想同时启动这些 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 ---"}
这是 运行 制作的东西。但是,如果一项工作在另一项工作之前准备就绪,它将产生僵尸。有没有可能让它变得简单而美丽?我尝试了一些带有 while 循环的 exp_after、exp_background、$any_spawn_id 的想法。但没有任何效果。期望永远不会得到eof。
如果您需要知道生成的命令完成的顺序,很难用 wait 来完成,但是 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 2
和 sleep 1
,并将每个生成 ID 附加到列表 allids
中。为方便起见,该命令也在数组 cmd
中注明,该数组由该命令的生成 ID 索引。
然后使用 -i
将所有生成 ID 的列表提供给 expect eof
。
当 eof 匹配时,全局变量 $expect_out(spawn_id)
包含导致匹配的进程的生成 ID。在 cmd
数组中索引此值后打印一条消息。
最后,从列表中删除带有eof的spawn id,并重复循环直到列表为空。
请注意,您不能使用 exp_continue
继续 expect 循环,因为 -i
值似乎没有被重新计算。
目前,我正在编写一个脚本来自动化数据收集器进程。通过长期 运行 我将这些 Collector 脚本分成了四个部分。现在我想同时启动这些 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 ---"}
这是 运行 制作的东西。但是,如果一项工作在另一项工作之前准备就绪,它将产生僵尸。有没有可能让它变得简单而美丽?我尝试了一些带有 while 循环的 exp_after、exp_background、$any_spawn_id 的想法。但没有任何效果。期望永远不会得到eof。
如果您需要知道生成的命令完成的顺序,很难用 wait 来完成,但是 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 2
和 sleep 1
,并将每个生成 ID 附加到列表 allids
中。为方便起见,该命令也在数组 cmd
中注明,该数组由该命令的生成 ID 索引。
然后使用 -i
将所有生成 ID 的列表提供给 expect eof
。
当 eof 匹配时,全局变量 $expect_out(spawn_id)
包含导致匹配的进程的生成 ID。在 cmd
数组中索引此值后打印一条消息。
最后,从列表中删除带有eof的spawn id,并重复循环直到列表为空。
请注意,您不能使用 exp_continue
继续 expect 循环,因为 -i
值似乎没有被重新计算。