data in Expect_out (buffer) that contains send
I always thought that once the send is executed in expect, expect_out (buffer) is emptied until new data is filled in, which is exactly what is used in the expect statement. And today in debugging, I was surprised to find the problem, the original expect_out (buffer) will not be automatically emptied, and expect to the data is probably not what you really want, very likely is historical data. This issue is also noted in the article "Expect_out (buffer) has the content of the previous send".
For example, in my code, there are fragments: set Prompt "#" set Lockfile "/root/tmp/.cool.lock" send "if/[-e $lockfile]; Then cat $lockfile else Echo/"Coolid: $coolid/" > $lockfile echo done! FI/R "Sleep 1; # necessary Expect {timeout {puts stderr ' WARNING: $ME: Cannot verify if the Linux AP is locked by Cool session! "; Exit 2; }-re "Coolid: (/[1-9) (/[0-9) *). * $prompt" {puts stdout "expect_out (buffer) = $expect _out (buffer)" puts stdout "expect_ Out (0,string) = $expect _out (0,string) "puts stdout" expect_out (1,string) = $expect _out (1,string) "puts stdout" expect_ Out (2,string) = $expect _out (2,string) "puts stdout" expect_out (3,string) = $expect _out (3,string) "}" done! "; Regardless of whether the $ lockfile exists, expect always gets coolid:68, and expect_out (buffer) comes out as follows:
[Root@bjvsmcl05 ~]# expect_out (buffer) = Login:fri June 09:32:13 from Bjbldd [root@bjvsmcl05 ~]# [ROOT@BJVSMCL ~]# if [-e/root/tmp/.cool.lock]; Then > Cat/root/tmp/.cool.lock > Else > echo "coolid:68" >/root/tmp/.cool.lock > Echo done! > Fi coolid:1234 [root@bjvsmcl05 ~]# [root@bjvsmcl05 ~]# expect_out (0,string) =23 09:32:13 from Bjbldd [ROOT@BJVSM Cl05 ~]# [Root@bjvsmcl05 ~]# if [-e/root/tmp/.cool.lock]; Then > Cat/root/tmp/.cool.lock > Else > echo "coolid:68" >/root/tmp/.cool.lock > Echo done! > Fi coolid:1234
Thus, since expect_out (buffer) contains Send's echo "coolid:68", it can always be matched to this data.
The expect_out (buffer) cannot be emptied in real time because there is no way to empty the expect_out (buffer). There are two kinds of solutions I can think of: one is to change the content or mode of send and expect to avoid expect patterns (pattern) in the contents of send. For example, in my program, change the above code snippet to: Set Lockfile "/root/tmp/.cool.lock" send "cat $lockfile/R" expect {-re "Coolid: (/[1-9] (/[0-9)) *)" {PU TS stdout "expect_out (buffer) = $expect _out (buffer)" puts stdout "expect_out (0,string) = $expect _out (0,string)" puts StdOut "expect_out (1,string) = $expect _out (1,string)" If {[string compare $expect _out (1,string) $coolid]} {puts stdout "E Rror: $ME: $pcname has been reserverd by cool session $expect _out (1,string), please choose another Linux PC instead./n "ex It 2; } "Cat: $lockfile: No such file or directory*" {send "echo/" Coolid: $coolid/"> $lockfile/R"} will work correctly.
Another method is to follow the method in the example of "expect_out (buffer) has the content of the previous send", set prompt, keep the contents of send in the original code unchanged, and change the expect regular expression to-r E "fi (. *) $prompt" so that the desired output is in Expect_out (1,string), and then the matching data is parsed using string or Lsearch commands.
Conclusion: In future, when writing expect script, we should consider not only the send/expect of each step, but also the expect content of this step may appear in previous historical data.