Notes about "Exploring Expect"

Chapter 3

  • Section "The expect Command": expect_out(0,string) can NOT be written as "expect_out(0, string)", blank before "string" will make a mistake;

  • Concurrent matching:

expect {

item1 {send cmd1}

item2 {send cmd2}

}

  • In spawn process, use " " as the return key in send command;

Chapter 5

  • Section "Using Parentheses For Feedback" give a clear and concise explanations of how to get feedback in expect.

#!/usr/bin/expect set timeout 60 expect -re "a(.*)c" send "expect_out(buffer) = ${expect_out(buffer)} " send "expect_out(0,string) = ${expect_out(0,string)} " send "expect_out(1,string) = ${expect_out(1,string)} " expect -re "e" send "expect_out(buffer) = ${expect_out(buffer)} " send "expect_out(0,string) = ${expect_out(0,string)} " send "expect_out(1,string) = ${expect_out(1,string)} "

Run this script, input "junk abcbcdef" and return, will produces:

$ ./feedback.exp junk abcbcdef expect_out(buffer) = junk abcbc expect_out(0,string) = abcbc expect_out(1,string) = bcb expect_out(buffer) = de expect_out(0,string) = e expect_out(1,string) = bcb

You can see value of "expect_out(...)" will be refreshed when a expect matches (expect "e"). "buffer" are all things from last buffer ("...cbc") to this match ("e"), which is "de" in this case. "0,string" means all matching strings (note "0, string" will raise a exception for the redundant blank). "1,string" means the first subgroup of "0,string". If there is no subgroup (expressed as parentheses) in current match, (1,string) remains last value ("bcb" in this case). Even "f" at the end of input has been sent to expect, it will not be added to "buffer", because it's not a part of the current match.

Chapter 6

  • exp_continue is useful in many circumstances. See its code example in section "Matching Multiple Times" in chapter 6 and section "Prompting For A Password On Behalf Of A Program" in chapter 8;

Chapter 7 & 8

  • some frequently used command:

log_file: write output of spawned process to a file; log_user: send output of spawned process to/not to user; send_user: expect script send messages to user;

expect_user: continue communicating with the user even after a process has been spawned; send: expect script send messages to spawned process; send_log: only write to log (without writing to stdout); send_error: expect script send messages to stderr; exp_internal: enable/disable internal diagnostics to stdout or log file (see section "Logging Internal Diagnostics");

  • proc sendexpect in section "The send_error Command" is useful;

  • right-wrong-timeout switch in section "The expect_user Command":

expect {

right {

} wrong {

send_error error_message

exit 1

} timeout {

send_error "time out!"

exit 1

}

}

  • A program switch between character and line mode. Notice the usage of "stty raw":

send_user "Now we are in line mode. You can use backspace to re-input. " send_user "Continue? y or n " expect_user -re "y|n" send_user "you press $expect_out(0,string) " stty raw send_user "Now we are in character mode. You have no chance to re-input. " send "Continue? Enter y or n: " expect -re "y|n" send_user " you press $expect_out(0,string)"

  • stty should be executed during times when the user is not typing, such as before a prompt rather than after, otherwise there is possibility of losing characters while switching modes. See the end of section "Line Versus Character-Oriented And Other Terminal Modes";

  • In the modified version of su2 in section "Echoing", I modified "# " to " #" in the last 3rd line, because on my platform (Mint Xfce 14) there are no space after "#" in the prompt of root user;

  • the get password procedure in section "Echo" is a must-have tool;

  • If you want exact Bourne-shell semantics, the simplest way is to call system. See section "The system Command";

Chapter 9

arguments experiment after #!

The echo.exp:

version 1:

#!/usr/bin/expect set argc [llength $argv] for {set i 0} {$i<$argc} {incr i} { puts "arg $i: [lindex $argv $i]" }

version 2:

#!/usr/bin/expect --

...

version 3:

#!/usr/bin/expect -f

...

Now run command ./echo.exp -c "puts hello" 1 2 3, the output is:

version 1:

arg 0: -c arg 1: puts hello arg 2: 1 arg 3: 2 arg 4: 3

version 2:

arg 0: -c arg 1: puts hello arg 2: 1 arg 3: 2 arg 4: 3

version 3:

hello arg 0: 1 arg 1: 2 arg 2: 3

So it is clear that only when "-f" is specified, "-c" means "take my arguments as a script". Otherwise "-c" will be treated as a common arguments of the script. "--" explicitly stop any arguments interpreting.

Chapter 17

  • this chapter describes how to make expect script a server;
原文地址:https://www.cnblogs.com/darkmatter/p/3606771.html