我已经编写了一个期望函数来获取命令的输出,我的代码如下所示
proc do_cmd {cmd id} {
set spawn_id $id
send "$cmd\r"
expect "$cmd\r"
expect {
-re "\n(.*)\r\n" {return $expect_out(1,string)}
default {exit 1}
}
}
如果我只调用一次它可以正常工作并返回我想要的东西,但如果我连续不停地调用它,它会返回不需要的东西。
# test case 1
set ret [do_cmd $mycmd $spawn_id]
puts "$mycmd returns $ret" # the return value is ok
# test case 2
set ret [do_cmd $mycmd $spawn_id]
set ret [do_cmd $mycmd $spawn_id]
puts "$mycmd returns $ret" # the return value is not something I want
我使用' exp_internal 1'调试它,发现第二个被调用命令中的expect_out仍然保存了先前的输出信息并导致了匹配问题,所以如何清理expect_out缓冲区(我试图将它设置为空字符串,但它没有&#t; t工作,)或者我还能做些什么来避免这个问题?提前谢谢。
答案 0 :(得分:10)
Don Libes对您的方案的建议如下,
有时甚至说:
expect *
这里*匹配任何东西。这就像说,"我不在乎什么 在输入缓冲区中。扔掉它。"这种模式总是匹配,甚至 如果什么都没有请记住*匹配任何东西,而空 字符串是什么!作为此行为的推论,此命令 总是马上回来。它永远不会等待新数据到来。它 没有,因为它匹配一切。
在这种情况下,在您需要的匹配之后,最好尝试将匹配保存到某个变量,然后只需在最后添加代码expect *
。这将清空缓冲区。您的代码可以更改如下。
proc do_cmd {cmd id} {
set spawn_id $id
send "$cmd\r"
#Looks like you are looking for a particular command to arrive
expect "$cmd\r"
#Then you have one more expect here which is you want to get it
expect {
#Saving the value sub match to the variable 'result'
-re "\n(.*)\r\n" {set result $expect_out(1,string)}}
}
#Causing the buffer to clear and it will return quickly
expect *
return $result
}
除此之外,还有一种方法可以取消expect_out(buffer)
内容本身,这将删除“缓冲区”。来自expect_out
数组的索引,可以描述为
unset expect_out(buffer)
当下一场比赛发生时,expect_out
阵列将更新索引'缓冲区'我们可以获得新的expect_out(buffer)
值。如果您愿意使用这种方式,请将expect *
替换为上述代码。
这是一种解决方法,可以实现我们想要的东西。您可以采取任何方法。选择是你的。 :)