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.

+3


source to share


1 answer


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.:)

+9


source







All Articles