How to clear the previous expect_buf while waiting for a script
I wrote a wait function to get the command output and my code looks like below
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}
}
}
If I call the function just once, it works fine and returns something I want, but if I call it continuously without interruption, it returns something unwanted.
# 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
I am using 'exp_internal 1' to debug it and found that the expect_out function in the second called command still contains the previous exit information and caused the matching problem, so how can I clear the expect_out buffer (I tried to set it to an empty string, but it doesn't works), or is there something else I can do to avoid this issue? Thanks in advance.
Don Libes' suggestion for your scenario looks like this:
Sometimes it is even helpful to say:
expect *
Here * matches anything. It's like saying, "I don't care what's in the input buffer. Drop it." This pattern always matches, even if nothing exists. Remember, * matches anything, and an empty string is anything! As a consequence of this behavior, this command always returns immediately. He never waits for new data. This is unnecessary as it fits everyone.
Ref: Exploring Expectations
In this case, after the required match, it is better to try to store the match with some variable, and then just add the code expect *
last. This will free the buffer. Your code can be modified as shown below.
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
}
In addition, there is another way to disable content expect_out(buffer)
, which will remove the index "buffer" from the array expect_out
, which can be rendered as
unset expect_out(buffer)
When the next match occurs, the array expect_out
will be updated with the index buffer and we can get the new value expect_out(buffer)
. Replace expect *
with the above code if you prefer using this method.
This is a pretty convenient way to get what we really want. You can use any approach. Your choice.:)