浅谈使用expect实现自动交互式(1)

来源:互联网 发布:怎么配置网络打印机 编辑:程序博客网 时间:2024/06/03 18:26

最近测试服务器的网络稳定性,网络老是不定时自动断开,开发人员也没法判定究竟哪里出问题了,一直反复尝试修改某些参数,使之工作正常,测试过程中反映我们之前用的测试手段,手动过程复杂麻烦,可否考虑写成脚本简化,为此找了些方法,最后发现了shell中的expect,python中的pexpect;下面就谈下最近的使用心得。

python 的可以参考:

http://www.ibm.com/developerworks/cn/linux/l-cn-pexpect2/

http://www.ibm.com/developerworks/cn/linux/l-cn-pexpect1/

linux 参考:

http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=1070390

http://blog.chinaunix.net/space.php?uid=20393955&do=blog&id=345046


1、首先介绍下,

Expect使用Tcl作为语言核心。不仅如此,不管程序是交互和还是非交互的,Expect都能运用。这是一个小语言和Unix的其他工具配合起来产生强大功能的经典例子。

Shell没有提供从一个程序读和向一个程序写的功能。这意味着shell可以运行fsck但只能以牺牲一部分fsck的灵活性做代价。有一些程序根本就不能被执行。比如说,如果没有一个用户接口交互式的提供输入,就没法运行下去。其他还有象Telnet,crypt,su,rlogin等程序无法在shell脚本里面自动执行。还有很多其他的应用程序在设计是也是要求用户输入的。

Expect被设计成专门针和交互式程序的交互。一个Expect程序员可以写一个脚本来描述程序和用户的对话。接着Expect程序可以非交互的运行“交互式”的程序。写交互式程序的脚本和写非交互式程序的脚本一样简单。Expect还可以用于对对话的一部分进行自动化,因为程序的控制可以在键盘和脚本之间进行切换。

Expect语言是基于Tcl的。Tcl实际上是一个子程序库,这些子程序库可以嵌入到程序里从而提供语言服务。 最终的语言有点象一个典型的Shell语言。里面有给变量赋值的set命令,控制程序执行的if,for,continue等命令,还能进行普通的数学和字符串操作。

spawn命令激活一个Unix程序来进行交互式的运行。 

send命令向进程发送字符串。

expect命令等待进程的某些字符串。 

expect支持正规表达式并能同时等待多个字符串,并对每一个字符串执行不同的操作。

expect还能理解一些特殊情况,如超时和遇到文件尾。

2、实例:

下面展示下用expect实现ssh配公钥的一个脚本:

      #!/usr/bin/expect
  4 spawn echo "######running to generate a ssh-public-key######"
  5 spawn ssh-keygen -t rsa
  6 expect " Enter file in which to save the key (/root/.ssh/id_rsa):"
  7 send "\r"

  9  expect "Overwrite (y/n)"
 10 send "y\r"
 11 expect "Enter passphrase (empty for no passphrase):"
 12 send "123456\r"
 13 expect "Enter same passphrase again:"
 14 send "123456\r"
 15 expect eof
 16 exit

输出:

Loong:~/ssh_test# ./ssh_modle.sh
spawn echo ######running to generate a ssh-public-key######
spawn ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
/root/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
df:2f:47:5b:49:df:1e:88:97:b4:d2:77:20:d1:c2:30 root@Loong
The key's randomart image is:
+--[ RSA 2048]----+
|          Eo .   |
|           .+ .  |
|             o   |
|            .... |
|        S   +.=.+|
|         . + *.+=|
|          . +..+o|
|            ..o .|
|             o.  |
+-----------------+
Loong:~/ssh_test#
以上便是使用自动交互的一个实例,类似的还可以进行ftp、ssh、密码修改等交互性的实现;上例中当然没有使用到变量,if分支语句等,想要脚本交互性更好的话,当然可以考虑进行加入;

3、安装:

直接用apt-get install expect  即可;

或者下载    

官网地址:

http://expect.nist.gov

   或:http://expect.sourceforge.net/

4、常识解释:

  1、expect命令介绍

    spawn:启动一个程序或进程

    send:给进程或程序返回结果

    expect:接受程序或进程输出

    interact:使用户处于进程或程序的交互状态

2、linux man中关于expect的用法说明:

5、Usage

Expect reads cmdfile for a list of commands to execute.Expect may also beinvoked implicitly on systems which support the #! notation by marking the script executable, and making the first line in your script:

#!/usr/local/bin/expect -f

Of course, the path must accurately describe where Expect lives. /usr/local/bin is just an example.

The -c flag prefaces a command to be executed before any in the script. The command should be quoted to prevent being broken up by the shell. Thisoption may be used multiple times. Multiple commands may be executed with a single-c by separating them with semicolons. Commands are executed in theorder they appear. (When using Expectk, this option is specified as-command.)

The -d flag enables some diagnostic output, which primarily reports internal activity of commands such asexpect andinteract. Thisflag has the same effect as "exp_internal 1" at the beginning of anExpect script, plus the version ofExpect is printed. (Thestrace command isuseful for tracing statements, and thetrace command is useful for tracing variable assignments.) (When using Expectk, this option is specified as-diag.)

The -D flag enables an interactive debugger. An integer value should follow. The debugger will take control before the next Tcl procedure if thevalue is non-zero or if a ^C is pressed (or a breakpoint is hit, or other appropriate debugger command appears in the script). See the README file or SEE ALSO(below) for more information on the debugger. (When using Expectk, this option is specified as-Debug.)

The -f flag prefaces a file from which to read commands from. The flag itself is optional as it is only useful when using the #! notation (seeabove), so that other arguments may be supplied on the command line. (When using Expectk, this option is specified as -file.)

By default, the command file is read into memory and executed in its entirety. It is occasionally desirable to read files one line at a time. For example,stdin is read this way. In order to force arbitrary files to be handled this way, use the-b flag. (When using Expectk, this option is specified as-buffer.)Notethatstdio-bufferingmaystilltakeplacehoweverthisshouldn'tcauseproblemswhenreadingfromafifoorstdin.

If the string "-" is supplied as a filename, standard input is read instead. (Use "./-" to read from a file actually named "-".)

The -i flag causes Expect to interactively prompt for commands instead of reading them from a file. Prompting is terminated via theexit command or upon EOF. Seeinterpreter (below) for more information. -i is assumed if neither a command file nor-c is used.(When using Expectk, this option is specified as-interactive.)

-- may be used to delimit the end of the options. This is useful if you want to pass an option-like argument to your script without it beinginterpreted byExpect. This can usefully be placed in the #! line to prevent any flag-like interpretation byExpect. For example, the following willleave the original arguments (including the script name) in the variableargv.

#!/usr/local/bin/expect --

Note that the usual getopt(3) andexecve(2) conventions must be observed when adding arguments to the #! line.

The file $exp_library/expect.rc is sourced automatically if present, unless the-N flag is used. (When using Expectk, this option is specified as-NORC.) Immediately after this, the file ~/.expect.rc is sourced automatically, unless the-n flag is used. If the environment variable DOTDIR isdefined, it is treated as a directory and .expect.rc is read from there. (When using Expectk, this option is specified as-norc.) This sourcing occursonly after executing any -c flags.

-v causes Expect to print its version number and exit. (The corresponding flag in Expectk, which uses long flag names, is -version.)

Optional args are constructed into a list and stored in the variable namedargv.argc is initialized to the length of argv.

argv0 is defined to be the name of the script (or binary if no script is used). For example, the following prints out the name of the script and thefirst three arguments:

send_user "$argv0 [lrange $argv 0 2]\n"

中文意思为:

用法:
    Expect通过读取cmdfile(命令文件)来执行一系列指令。只要系统支持“#!“,在Script脚本文件的首行标明“#!/usr
/local/bin/expect –f“,并赋予脚本文件可执行权限,执行脚本文件就可以(隐含方式或是默认)调用Expect。
    当然,上面的路径必须正确地指明Expect解释程序的位置。/usr/local/bin只是一个例子。
    -c 选项用来标明需要在执行脚本内容之前来执行的命令。
      这条命令(-c选项后的命令)应该用引号括起来,以免在执行时被shell分开解释。
      -c选项可能会被反复使用。多条命令可以使用同一个”-c”,命令之间需要用分号隔开。这些命令会按照它们出现的先后顺序执行。(在Expectk中,”-c”相当于”-command”)。
    -d 选项允许输出调试性信息。这些信息主要报告像expect和interact等命令执行时的内部行为。这个选项与写在脚本开头的”exp_internal1”具有同样的效果,同时还会打印出Expect的版本。(strace命令用在跟踪变量声明,trace命令用于跟踪变量的赋值)(在Expectk中,”-d”相当于”-diag”)
    -D选项开启交互调试器。后面必须跟有一个整数值作为参数,当值为非零或是按下CTRL+C的时候(或是遇到断点,或是在脚本中恰好出现其他的调试语句),
调试器会在进行下一次Tcl Procedure前取得控制权。想了解更多信息请参见README文件或是下面的SEE
ALSO。(在Expectk中,这个选项相当于”-Debug”)。
    - f 选项指明从哪个文件中读取命令。这个选项是可选的,因为只有当使用”#!”时它才有可能被用到。而其他选项可以写在命令行中。(在Expectk中,它相当于”-file”)。
    默认情况下,命令文件是全部读入内存一并执行的。但有些时候需要每次只读一行。例如:stdin(标准输入)就是这样读取的。如果强制任意文件以这种方式(每次读一行)执行的话就使用”-b”选项。(在Expectk中,它相当于”-buffer”)。
    如果”-“被一个文件名替代,那么脚本就会用读指定文件的方式来替代从标准输入读的方式。(例如:”./ -“就表示从一个名为”-”的文件中读所需的信息)。
    -i选项使Expect能交互式的提示输入命令,而不是从文件中读取。在遇到文件尾或是执行了exit命令时,提示输入命令终止。要了解更多信息请参见下面的
interpreter。-i选项是假设既不是从一个命令文件读,也没有使用-c选项。(在Expectk中,它相当于”-interactive”)。
    -- 是用来为划定选项尾的。当你需要像使用选项一样传一个参数,但希望这个参数不要被当作选项解释时,就需要用到这个选项。当阻止其他选项时,可以把它放在”#!”行中。例如:下面的例子会让所有参数(包括脚本文件名)都存储在argv中。
    #!/usr/local/bin/expect --
注意:当在”#!”行中使用参数时,必须遵守getopt(3)和execve(2)的规定。
    $exp_library下如果有expect.rc这个文件的话,它会自动被加载为资源文件(应该是类似于标准配置文件,像用户根目录下
的.bash_profile文件一样)。除非使用-N选项取消自动加载。(在Expectk中,它相当于”-NORC”)。这个文件被加载后,紧接着用
户根目录下的.expect.rc(~/.expect.rc)会被加载。除使用-n选项取消。如果定义了环境变量DOTDIR,那么它被认为是存放
有.expect.rc文件的目录。然后从这个目录中读取.expect.rc文件。(在Expectk中,它相当于”-norc”)。这些加载配置文件
的动作是出现在执行完-c选项指定的命令之后。
    -v 选项用来打印出版本号,然后退出。(在Expectk中的相应选项是-version)。
    可选的参数汇成一列,存放在变量argv中。Argc被初始化为argv的长度(变量个数)。Argv0被设置为脚本名称(or binary if no script is used)。例如:下面的例子打印出脚本的名称和前三个参数。
    Send_user “$argv0 [lrang $argv 0 2 ]\n”

6、Commands

Expect uses Tcl (Tool Command Language). Tcl provides control flow (e.g., if, for,break), expression evaluation and several other features such as recursion, procedure definition, etc. Commands used here but not defined (e.g., set,if, exec) are Tcl commands (seetcl(3)).Expect supports additional commands, described below. Unless otherwise specified, commandsreturn the empty string.

Commands are listed alphabetically so that they can be quickly located. However, new users may find it easier to start by reading the descriptions ofspawn,send,expect, andinteract, in that order.

Note that the best introduction to the language (both Expect and Tcl) is provided in the book "Exploring Expect" (see SEE ALSO below). Examples are includedin this man page but they are very limited since this man page is meant primarily as reference material.

Note that in the text of this man page, "Expect" with an uppercase "E" refers to theExpect program while "expect" with a lower-case "e" refers totheexpect command within the Expect program.)

close [-slave] [-onexec 0|1] [-i spawn_id]
closes the connection to the current process. Most interactive programs will detect EOF on their stdin and exit; thusclose usually suffices to killthe process as well. The-i flag declares the process to close corresponding to the named spawn_id.

Both expect and interact will detect when the current process exits and implicitly do aclose. But if you kill the process by, say,"exec kill $pid", you will need to explicitly callclose.

The -onexec flag determines whether the spawn id will be closed in any new spawned processes or if the process is overlayed. To leave a spawn idopen, use the value 0. A non-zero integer value will force the spawn closed (the default) in any new processes.

The -slave flag closes the slave associated with the spawn id. (See "spawn -pty".) When the connection is closed, the slave is automatically closedas well if still open.

No matter whether the connection is closed implicitly or explicitly, you should callwait to clear up the corresponding kernel process slot.close does not callwait since there is no guarantee that closing a process connection will cause it to exit. Seewait below for moreinfo.

debug [[-now] 0|1]
controls a Tcl debugger allowing you to step through statements, set breakpoints, etc.

With no arguments, a 1 is returned if the debugger is not running, otherwise a 0 is returned.

With a 1 argument, the debugger is started. With a 0 argument, the debugger is stopped. If a 1 argument is preceded by the-now flag, the debugger isstarted immediately (i.e., in the middle of thedebug command itself). Otherwise, the debugger is started with the next Tcl statement.

The debug command does not change any traps. Compare this to startingExpect with the-D flag (see above).

See the README file or SEE ALSO (below) for more information on the debugger.

disconnect
disconnects a forked process from the terminal. It continues running in the background. The process is given its own process group (if possible). StandardI/O is redirected to /dev/null.
The following fragment uses
disconnect to continue running the script in the background.
if {[fork]!=0} exitdisconnect. . .
The following script reads a password, and then runs a program every hour that demands a password each time it is run. The script supplies the password so thatyou only have to type it once. (See thestty command which demonstrates how to turn off password echoing.)
send_user "password?\ "expect_user -re "(.*)\n"for {} 1 {} {    if {[fork]!=0} {sleep 3600;continue}    disconnect    spawn priv_prog    expect Password:    send "$expect_out(1,string)\r"    . . .    exit}
An advantage to using disconnect over the shell asynchronous process feature (&) is thatExpect can save the terminal parameters prior todisconnection, and then later apply them to new ptys. With &,Expect does not have a chance to read the terminal's parameters since the terminal isalready disconnected by the timeExpect receives control.
exit [-opts] [status]
causes Expect to exit or otherwise prepare to do so.

The -onexit flag causes the next argument to be used as an exit handler. Without an argument, the current exit handler is returned.

The -noexit flag causes Expect to prepare to exit but stop short of actually returning control to the operating system. The user-defined exithandler is run as well asExpect's own internal handlers. No further Expect commands should be executed. This is useful if you are runningExpect with otherTcl extensions. The current interpreter (and main window if in the Tk environment) remain so that other Tcl extensions can clean up. IfExpect'sexit iscalled again (however this might occur), the handlers are not rerun.

Upon exiting, all connections to spawned processes are closed. Closure will be detected as an EOF by spawned processes.exit takes no other actionsbeyond what the normal_exit(2) procedure does. Thus, spawned processes that do not check for EOF may continue to run. (A variety of conditions are importantto determining, for example, what signals a spawned process will be sent, but these are system-dependent, typically documented underexit(3).) Spawnedprocesses that continue to run will be inherited by init.

status (or 0 if not specified) is returned as the exit status of Expect. exit is implicitly executed if the end of the script isreached.

exp_continue [-continue_timer]
The command exp_continue allows expect itself to continue executing rather than returning as it normally would. By defaultexp_continue resets the timeout timer. The-continue_timer flag prevents timer from being restarted. (See expect for more information.)
exp_internal[-f file] value
causes further commands to send diagnostic information internal to Expect to stderr ifvalue is non-zero. This output is disabled ifvalue is 0. The diagnostic information includes every character received, and every attempt made to match the current output against the patterns.
If the optional
file is supplied, all normal and debugging output is written to that file (regardless of the value ofvalue). Any previous diagnostic outputfile is closed.

The -info flag causes exp_internal to return a description of the most recent non-info arguments given.

exp_open [args] [-i spawn_id]
returns a Tcl file identifier that corresponds to the original spawn id. The file identifier can then be used as if it were opened by Tcl'sopencommand. (The spawn id should no longer be used. Await should not be executed.

The -leaveopen flag leaves the spawn id open for access throughExpect commands. Await must be executed on the spawn id.

exp_pid [-i spawn_id]
returns the process id corresponding to the currently spawned process. If the-i flag is used, the pid returned corresponds to that of the givenspawn id.
exp_send
is an alias for send.
exp_send_error
is an alias for send_error.
exp_send_log
is an alias for send_log.
exp_send_tty
is an alias for send_tty.
exp_send_user
is an alias for send_user.
exp_version [[-exit] version]
is useful for assuring that the script is compatible with the current version ofExpect.
With no arguments, the current version of
Expect is returned. This version may then be encoded in your script. If you actually know that you are not using features of recent versions, youcan specify an earlier version.
Versions consist of three numbers separated by dots. First
is the major number. Scripts written for versions of Expect with a different major number will almost certainly not work.exp_version returnsan error if the major numbers do not match.
Second is the minor number. Scripts written for a version with a
greater minor number than the current version may depend upon some new feature and might not run.exp_version returns an error if the major numbersmatch, but the script minor number is greater than that of the runningExpect.
Third is a number that plays no part in the version comparison.
However, it is incremented when the Expect software distribution is changed in any way, such as by additional documentation or optimization. It isreset to 0 upon each new minor version.
With the
-exit flag, Expect prints an error and exits if the version is out of date.
expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]
waits until one of the patterns matches the output of a spawned process, a specified time period has passed, or an end-of-file is seen. If the final bodyis empty, it may be omitted.
Patterns from the most recent
expect_before command are implicitly used before any other patterns. Patterns from the most recentexpect_after command are implicitly usedafter any other patterns.
If the arguments to the entire
expect statement require more than one line, all the arguments may be "braced" into one so as to avoid terminating each line with a backslash. Inthis one case, the usual Tcl substitutions will occur despite the braces.
If a pattern is the keyword
eof, the corresponding body is executed upon end-of-file. If a pattern is the key wordtimeout, the corresponding body is executed upon timeout. If no timeout keyword is used, an implicit null action is executed upon timeout. The default timeout period is 10 seconds but may be set, for example to 30, by the command "set timeout 30". An infinite timeout may be designated by the value -1. If a pattern is the key word default, the corresponding body is executed upon either timeout or end-of-file.
If a pattern matches, then the corresponding body is executed.
expect returns the result of the body (or the empty string if no pattern matched). In the event that multiple patterns match, the one appearingfirst is used to select a body.
Each time new output arrives, it is compared to each pattern in the order
they are listed. Thus, you may test for absence of a match by making the last pattern something guaranteed to appear, such as a prompt. In situations where there is no prompt, you must usetimeout (just like you would if you were interacting manually).
Patterns are specified in three ways. By default,
patterns are specified as with Tcl's string match command. (Such patterns are also similar to C-shell regular expressions usually referred to as"glob" patterns). The-gl flag may may be used to protect patterns that might otherwise matchexpect flags from doing so. Any pattern beginningwith a "-" should be protected this way. (All strings starting with "-" are reserved for future options.)
For example, the following fragment looks for a successful login.
(Note that abort is presumed to be a procedure defined elsewhere in the script.)
expect {    busy               {puts busy\n ; exp_continue}    failed             abort    "invalid password" abort    timeout            abort    connected}
Quotes are necessary on the fourth pattern since it contains a space, which would otherwise separate the pattern from the action. Patterns with the same action(such as the 3rd and 4th) require listing the actions again. This can be avoid by using regexp-style patterns (see below). More information on formingglob-style patterns can be found in the Tcl manual.
Regexp-style patterns follow the syntax defined by Tcl's
regexp (short for "regular expression") command. regexp patterns are introduced with the flag-re. The previous example can be rewrittenusing a regexp as:
expect {    busy       {puts busy\n ; exp_continue}    -re "failed|invalid password" abort    timeout    abort    connected}
Both types of patterns are "unanchored". This means that patterns do not have to match the entire string, but can begin and end the match anywhere in thestring (as long as everything else matches). Use ^ to match the beginning of a string, and $ to match the end. Note that if you do not wait for the end of astring, your responses can easily end up in the middle of the string as they are echoed from the spawned process. While still producing correct results, theoutput can look unnatural. Thus, use of $ is encouraged if you can exactly describe the characters at the end of a string.

Note that in many editors, the ^ and $ match the beginning and end of lines respectively. However, becauseexpect is not line oriented, these charactersmatch the beginning and end of the data (as opposed to lines) currently in theexpect matching buffer. (Also, see the note below on "system indigestion.")

The -ex flag causes the pattern to be matched as an "exact" string. No interpretation of *, ^, etc is made (although the usual Tcl conventions muststill be observed). Exact patterns are always unanchored.

The
-nocase flag causes uppercase characters of the output to compare as if they were lowercase characters. The pattern is not affected.
While reading output,
more than 2000 bytes can force earlier bytes to be "forgotten". This may be changed with the functionmatch_max. (Note that excessively large valuescan slow down the pattern matcher.) Ifpatlist isfull_buffer, the corresponding body is executed ifmatch_max bytes have been receivedand no other patterns have matched. Whether or not thefull_buffer keyword is used, the forgotten characters are written to expect_out(buffer).

If patlist is the keyword null, and nulls are allowed (via theremove_nulls command), the corresponding body is executed if a singleASCII 0 is matched. It is not possible to match 0 bytes via glob or regexp patterns.

Upon matching a pattern (or eof or full_buffer), any matching and previously unmatched output is saved in the variableexpect_out(buffer). Up to 9regexp substring matches are saved in the variablesexpect_out(1,string) throughexpect_out(9,string). If the -indices flag is used beforea pattern, the starting and ending indices (in a form suitable forlrange) of the 10 strings are stored in the variablesexpect_out(X,start) andexpect_out(X,end) where X is a digit, corresponds to the substring position in the buffer. 0 refers to strings which matched the entire pattern and isgenerated for glob patterns as well as regexp patterns. For example, if a process has produced output of "abcdefgh\n", the result of:

expect "cd"
is as if the following statements had executed:
set expect_out(0,string) cdset expect_out(buffer) abcd
and "efgh\n" is left in the output buffer. If a process produced the output "abbbcabkkkka\n", the result of:
expect -indices -re "b(b*).*(k+)"
is as if the following statements had executed:
set expect_out(0,start) 1set expect_out(0,end) 10set expect_out(0,string) bbbcabkkkkset expect_out(1,start) 2set expect_out(1,end) 3set expect_out(1,string) bbset expect_out(2,start) 10set expect_out(2,end) 10set expect_out(2,string) kset expect_out(buffer) abbbcabkkkk
and "a\n" is left in the output buffer. The pattern "*" (and -re ".*") will flush the output buffer without reading any more output from the process.
Normally, the matched output is discarded from Expect's internal buffers.
This may be prevented by prefixing a pattern with the -notransfer flag. This flag is especially useful in experimenting (and can be abbreviated to"-not" for convenience while experimenting).

The spawn id associated with the matching output (or eof or full_buffer) is stored inexpect_out(spawn_id).

The -timeout flag causes the current expect command to use the following value as a timeout instead of using the value of the timeout variable.

By default, patterns are matched against output from the current process, however the-i flag declares the output from the named spawn_id list bematched against any following patterns (up to the next-i). The spawn_id list should either be a whitespace separated list of spawn_ids or a variablereferring to such a list of spawn_ids.

For example, the following example waits for "connected" from the current process, or "busy", "failed" or "invalid password" from the spawn_id named by$proc2.

expect {    -i $proc2 busy {puts busy\n ; exp_continue}    -re "failed|invalid password" abort    timeout abort    connected}
The value of the global variable any_spawn_id may be used to match patterns to any spawn_ids that are named with all other-i flags in thecurrentexpect command. The spawn_id from a-i flag with no associated pattern (i.e., followed immediately by another-i) is madeavailable to any other patterns in the sameexpect command associated withany_spawn_id.

The -i flag may also name a global variable in which case the variable is read for a list of spawn ids. The variable is reread whenever it changes.This provides a way of changing the I/O source while the command is in execution. Spawn ids provided this way are called "indirect" spawn ids.

Actions such as break and continue cause control structures (i.e.,for,proc) to behave in the usual way. The commandexp_continue allowsexpect itself to continue executing rather than returning as it normally would.

This is useful for avoiding explicit loops or repeated expect statements.
The following example is part of a fragment to automate rlogin. The exp_continue avoids having to write a secondexpect statement (to lookfor the prompt again) if the rlogin prompts for a password.
expect {    Password: {        stty -echo        send_user "password (for $user) on $host: "        expect_user -re "(.*)\n"        send_user "\n"        send "$expect_out(1,string)\r"        stty echo        exp_continue    } incorrect {        send_user "invalid password or account\n"        exit    } timeout {        send_user "connection to $host timed out\n"        exit    } eof {        send_user \            "connection to host failed: $expect_out(buffer)"        exit    } -re $prompt}
For example, the following fragment might help a user guide an interaction that is already totally automated. In this case, the terminal is put into raw mode.If the user presses "+", a variable is incremented. If "p" is pressed, several returns are sent to the process, perhaps to poke it in some way, and "i" letsthe user interact with the process, effectively stealing away control from the script. In each case, theexp_continue allows the currentexpectto continue pattern matching after executing the current action.
stty raw -echoexpect_after {    -i $user_spawn_id    "p" {send "\r\r\r"; exp_continue}    "+" {incr foo; exp_continue}    "i" {interact; exp_continue}    "quit" exit}
By default,
exp_continue resets the timeout timer. The timer is not restarted, ifexp_continue is called with the-continue_timer flag.
expect_after [expect_args]
works identically to the expect_before except that if patterns from bothexpect andexpect_after can match, theexpect patternis used. See theexpect_before command for more information.
expect_background [expect_args]
takes the same arguments as expect, however it returns immediately. Patterns are tested whenever new input arrives. The patterntimeout anddefault are meaningless toexpect_background and are silently discarded. Otherwise, theexpect_background command usesexpect_before andexpect_after patterns just likeexpect does.

When expect_background actions are being evaluated, background processing for the same spawn id is blocked. Background processing is unblocked whenthe action completes. While background processing is blocked, it is possible to do a (foreground)expect on the same spawn id.

It is not possible to execute an expect while anexpect_background is unblocked.expect_background for a particular spawn id is deletedby declaring a new expect_background with the same spawn id. Declaringexpect_background with no pattern removes the given spawn id from the ability tomatch patterns in the background.

expect_before [expect_args]
takes the same arguments as expect, however it returns immediately. Pattern-action pairs from the most recentexpect_before with the samespawn id are implicitly added to any followingexpect commands. If a pattern matches, it is treated as if it had been specified in theexpectcommand itself, and the associated body is executed in the context of theexpect command. If patterns from bothexpect_before and expectcan match, theexpect_before pattern is used.

If no pattern is specified, the spawn id is not checked for any patterns.

Unless overridden by a -i flag, expect_before patterns match against the spawn id defined at the time that theexpect_before commandwas executed (not when its pattern is matched).

The -info flag causes expect_before to return the current specifications of what patterns it will match. By default, it reports on the current spawnid. An optional spawn id specification may be given for information on that spawn id. For example

expect_before -info -i $proc
At most one spawn id specification may be given. The flag -indirect suppresses direct spawn ids that come only from indirect specifications.

Instead of a spawn id specification, the flag "-all" will cause "-info" to report on all spawn ids.

The output of the -info flag can be reused as the argument to expect_before.

expect_tty [expect_args]
is like expect but it reads characters from /dev/tty (i.e. keystrokes from the user). By default, reading is performed in cooked mode. Thus, linesmust end with a return in order forexpect to see them. This may be changed viastty (see the stty command below).
expect_user[expect_args]
is like expect but it reads characters from stdin (i.e. keystrokes from the user). By default, reading is performed in cooked mode. Thus, lines mustend with a return in order forexpect to see them. This may be changed viastty (see the stty command below).
fork
creates a new process. The new process is an exact copy of the current Expect process. On success, fork returns 0 to the new (child) processand returns the process ID of the child process to the parent process. On failure (invariably due to lack of resources, e.g., swap space, memory), forkreturns -1 to the parent process, and no child process is created.
Forked processes exit via the
exit command, just like the original process. Forked processes are allowed to write to the log files. If you do not disable debugging or logging inmost of the processes, the result can be confusing.
Some pty implementations may be confused by multiple readers and writers,
even momentarily. Thus, it is safest to fork before spawning processes.
interact [string1 body1] ... [stringn [bodyn]]
gives control of the current process to the user, so that keystrokes are sent to the current process, and the stdout and stderr of the current process arereturned.
String-body pairs may be specified as arguments, in which case the
body is executed when the corresponding string is entered. (By default, the string is not sent to the current process.) Theinterpreter command isassumed, if the final body is missing.
If the arguments to the entire
interact statement require more than one line, all the arguments may be "braced" into one so as to avoid terminating each line with a backslash. Inthis one case, the usual Tcl substitutions will occur despite the braces.
For example, the following command runs interact with the following
string-body pairs defined: When ^Z is pressed, Expect is suspended. (The-reset flag restores the terminal modes.) When ^A is pressed, theuser sees "you typed a control-A" and the process is sent a ^A. When $ is pressed, the user sees the date. When ^C is pressed,Expect exits. If "foo" isentered, the user sees "bar". When ~~ is pressed, theExpect interpreter runs interactively.
set CTRLZ \032interact {    -reset $CTRLZ {exec kill -STOP [pid]}    \001   {send_user "you typed a control-A\n";            send "\001"           }    $      {send_user "The date is [clock format [clock seconds]]."}    \003   exit    foo    {send_user "bar"}    ~~}
In string-body pairs, strings are matched in the order they are listed
as arguments. Strings that partially match are not sent to the current process in anticipation of the remainder coming. If characters are then entered suchthat there can no longer possibly be a match, only the part of the string will be sent to the process that cannot possibly begin another match. Thus, stringsthat are substrings of partial matches can match later, if the original strings that was attempting to be match ultimately fails.
By default, string matching is exact with no wild cards. (In contrast,
the expect command uses glob-style patterns by default.) The-ex flag may be used to protect patterns that might otherwise matchinteract flags from doing so. Any pattern beginning with a "-" should be protected this way. (All strings starting with "-" are reserved for futureoptions.)

The -re flag forces the string to be interpreted as a regexp-style pattern. In this case, matching substrings are stored in the variableinteract_out similarly to the wayexpect stores its output in the variableexpect_out. The -indices flag is similarly supported.

The pattern eof introduces an action that is executed upon end-of-file. A separateeof pattern may also follow the-output flag inwhich case it is matched if an eof is detected while writing output. The defaulteof action is "return", so thatinteract simply returns upon anyEOF.

The pattern timeout introduces a timeout (in seconds) and action that is executed after no characters have been read for a given time. Thetimeout pattern applies to the most recently specified process. There is no default timeout. The special variable "timeout" (used by the expectcommand) has no affect on this timeout.

For example, the following statement could be used to autologout users who have not typed anything for an hour but who still get frequent systemmessages:

interact -input $user_spawn_id timeout 3600 return -output \    $spawn_id
If the pattern is the keyword null, and nulls are allowed (via theremove_nulls command), the corresponding body is executed if a single ASCII0 is matched. It is not possible to match 0 bytes via glob or regexp patterns.

Prefacing a pattern with the flag -iwrite causes the variableinteract_out(spawn_id) to be set to the spawn_id which matched the pattern (oreof).

Actions such as break and continue cause control structures (i.e.,for,proc) to behave in the usual way. Howeverreturncauses interact to return to its caller, whileinter_return causesinteract to cause a return in its caller. For example, if "proc foo" calledinteract which then executed the actioninter_return,proc foo would return. (This means that ifinteract callsinterpreterinteractively typingreturn will cause the interact to continue, whileinter_return will cause the interact to return to its caller.)

During
interact, raw mode is used so that all characters may be passed to the current process. If the current process does not catch job control signals,it will stop if sent a stop signal (by default ^Z). To restart it, send a continue signal (such as by "kill -CONT <pid>"). If you really want to send aSIGSTOP to such a process (by ^Z), consider spawning csh first and then running your program. On the other hand, if you want to send a SIGSTOP toExpectitself, first call interpreter (perhaps by using an escape character), and then press ^Z.
String-body pairs can be used as a shorthand for avoiding having
to enter the interpreter and execute commands interactively. The previous terminal mode is used while the body of a string-body pair is being executed.
For speed, actions execute in raw mode by default. The
-reset flag resets the terminal to the mode it had before interact was executed (invariably, cooked mode). Note that characters entered whenthe mode is being switched may be lost (an unfortunate feature of the terminal driver on some systems). The only reason to use-reset is if your actiondepends on running in cooked mode.
The
-echo flag sends characters that match the following pattern back to the process that generated them as each character is read. This may be usefulwhen the user needs to see feedback from partially typed patterns.
If a pattern is being echoed but eventually fails to match,
the characters are sent to the spawned process. If the spawned process then echoes them, the user will see the characters twice.-echo is probablyonly appropriate in situations where the user is unlikely to not complete the pattern. For example, the following excerpt is from rftp, the recursive-ftpscript, where the user is prompted to enter ~g, ~p, or ~l, to get, put, or list the current directory recursively. These are so far away from the normal ftpcommands, that the user is unlikely to type ~ followed by anything else, except mistakenly, in which case, they'll probably just ignore the result anyway.
interact {    -echo ~g {getcurdirectory 1}    -echo ~l {getcurdirectory 0}    -echo ~p {putcurdirectory}}
The -nobuffer flag sends characters that match the following pattern on to the output process as characters are read.

This is useful when you wish to let a program echo back the pattern. For example, the following might be used to monitor where a person is dialing (aHayes-style modem). Each time "atd" is seen the script logs the rest of the line.

proc lognumber {} {    interact -nobuffer -re "(.*)\r" return    puts $log "[clock format [clock seconds]]: dialed $interact_out(1,string)"}interact -nobuffer "atd" lognumber
During
interact, previous use of log_user is ignored. In particular,interact will force its output to be logged (sent to the standardoutput) since it is presumed the user doesn't wish to interact blindly.
The
-o flag causes any following key-body pairs to be applied to the output of the current process. This can be useful, for example, when dealing withhosts that send unwanted characters during a telnet session.
By default,
interact expects the user to be writing stdin and reading stdout of theExpect process itself. The-u flag (for "user") makesinteract look for the user as the process named by its argument (which must be a spawned id).
This allows two unrelated processes to be joined
together without using an explicit loop. To aid in debugging, Expect diagnostics always go to stderr (or stdout for certain logging and debugginginformation). For the same reason, theinterpreter command will read interactively from stdin.
For example, the following fragment creates a login process.
Then it dials the user (not shown), and finally connects the two together. Of course, any process may be substituted for login. A shell, for example, wouldallow the user to work without supplying an account and password.
spawn loginset login $spawn_idspawn tip modem# dial back out to user# connect user to logininteract -u $login
To send output to multiple processes, list each spawn id list prefaced by a -output flag. Input for a group of output spawn ids may be determined by aspawn id list prefaced by a-input flag. (Both-input and-output may take lists in the same form as the-i flag in theexpect command, except that any_spawn_id is not meaningful ininteract.) All following flags and strings (or patterns) apply to this input untilanother -input flag appears. If no-input appears,-output implies "-input $user_spawn_id -output". (Similarly, with patterns that do not have-input.) If one-input is specified, it overrides $user_spawn_id. If a second-input is specified, it overrides $spawn_id. Additional-input flags may be specified.

The two implied input processes default to having their outputs specified as $spawn_id and $user_spawn_id (in reverse). If a-input flag appears withno-output flag, characters from that process are discarded.

The -i flag introduces a replacement for the current spawn_id when no other-input or-output flags are used. A -i flag implies a -oflag.

It is possible to change the processes that are being interacted with by using indirect spawn ids. (Indirect spawn ids are described in the section on theexpect command.) Indirect spawn ids may be specified with the -i, -u, -input, or -output flags.

interpreter " [args]"
causes the user to be interactively prompted for Expect and Tcl commands. The result of each command is printed.
Actions such as
break and continue cause control structures (i.e.,for,proc) to behave in the usual way. Howeverreturn causesinterpreter to return to its caller, whileinter_return causesinterpreter to cause a return in its caller. For example, if "proc foo" calledinterpreter which then executed the actioninter_return,proc foo would return. Any other command causesinterpreter to continueprompting for new commands.
By default, the prompt contains two integers.
The first integer describes the depth of the evaluation stack (i.e., how many times Tcl_Eval has been called). The second integer is the Tcl historyidentifier. The prompt can be set by defining a procedure called "prompt1" whose return value becomes the next prompt. If a statement has open quotes, parens,braces, or brackets, a secondary prompt (by default "+> ") is issued upon newline. The secondary prompt may be set by defining a procedure called "prompt2".
During
interpreter, cooked mode is used, even if the its caller was using raw mode.
If stdin is closed,
interpreter will return unless the -eof flag is used, in which case the subsequent argument is invoked.
log_file[args] [[-a] file]
If a filename is provided, log_file will record a transcript of the session (beginning at that point) in the file.log_file will stoprecording if no argument is given. Any previous log file is closed.

Instead of a filename, a Tcl file identifier may be provided by using the -open or -leaveopen flags. This is similar to the spawncommand. (See spawn for more info.)

The -a flag forces output to be logged that was suppressed by thelog_user command.

By default, the log_file command appends to old files rather than truncating them, for the convenience of being able to turn logging off andon multiple times in one session. To truncate files, use the-noappend flag.

The -info flag causes log_file to return a description of the most recent non-info arguments given.

log_user -info|0|1
By default, the send/expect dialogue is logged to stdout (and a logfile if open). The logging to stdout is disabled by the command "log_user 0" andreenabled by "log_user 1". Logging to the logfile is unchanged.

The -info flag causes log_user to return a description of the most recent non-info arguments given.

match_max [-d] [-i spawn_id] [size]
defines the size of the buffer (in bytes) used internally by expect. With nosize argument, the current size is returned.
With the
-d flag, the default size is set. (The initial default is 2000.) With the-i flag, the size is set for the named spawn id, otherwise it isset for the current process.
overlay [-# spawn_id] [-# spawn_id] [...] program [args]
executes program args in place of the current Expect program, which terminates. A bare hyphen argument forces a hyphen in front of thecommand name as if it was a login shell. All spawn_ids are closed except for those named as arguments. These are mapped onto the named file identifiers.
Spawn_ids are mapped to file identifiers for the new program to inherit.
For example, the following line runs chess and allows it to be controlled by the current process - say, a chess master.
overlay -0 $spawn_id -1 $spawn_id -2 $spawn_id chess
This is more efficient than "interact -u", however, it sacrifices the ability to do programmed interaction since theExpect process is no longer incontrol.
Note that no controlling terminal is provided. Thus, if you
disconnect or remap standard input, programs that do job control (shells, login, etc) will not function properly.
parity [-d] [-i spawn_id] [value]
defines whether parity should be retained or stripped from the output of spawned processes. Ifvalue is zero, parity is stripped, otherwise it isnot stripped. With novalue argument, the current value is returned.
With the
-d flag, the default parity value is set. (The initial default is 1, i.e., parity is not stripped.) With the-i flag, the parity value is setfor the named spawn id, otherwise it is set for the current process.
remove_nulls [-d] [-i spawn_id] [value]
defines whether nulls are retained or removed from the output of spawned processes before pattern matching or storing in the variableexpect_out orinteract_out. Ifvalue is 1, nulls are removed. Ifvalue is 0, nulls are not removed. With novalue argument, the current value isreturned.
中文:

命令:
    Expect使用Tcl语言(Tool Command Language).Tcl提供诸如流控制,表达式值和一些其他的特性。像递归调用,定义函数等等。在这里用到的没有说明的命令都是Tcl命令。
    Expect支持一些额外的命令。下面具体描述。除非另外声明,否则命令返回空字符串。命令按字母顺序排序,这样便于查找。仅管如此,初学者还是觉得按照”spawn , send , expect , interact”这种方式来读比较容易。
    注意,Exploring Expect这本书中提供了关于”Expect和Tcl”的介绍.这本Manpage手册中也提供了一些例子.但数量有限,因为这本是做为入门的教材手册使用的.
    在本手册中,以E开头的是指Expect程序,小写e开头的是指expect命令.
    close [-slave] [-onexec 0|1] [-i spawn_id]
  
关闭与当前进程的连接.大多数交互程序会在它们的stdin(标准输入)中检测到EOF(文件尾),然后退出.所以通常close也有能力杀死进
程.-i选项指定了要杀死的对应于spawn_id的进程.expect和interact都能检测到当前程序的退出,并隐含的执行一个关闭.如果你通过
执行”exec kill $pid”来杀死进程的话,那么你就需要再显式的调用一下close.
    -onexec选项用来确定spawn_id在开始新的spawned
process(我将其翻译为监测进程)时是被关闭还是要被覆盖.如果想保持这个spawn_id打开的话,那么后面的参数需要设为0.一个非零值将会使
spawn_id关闭,并可以将这个spawn_id用于新的进程(默认行为).-slave选项是用来关闭从属进程.(参见spawn
-pty)。如果在连接中止的时候,从属进程还打开的话,那么它将自动关闭。不管进程是显式的调用或是隐式的被中止,你都需要调用wait命令来清理进程
执行的残余。Close不会调用wait。因为在关闭进程的时候,并不能保障它“正常退出”(个人认为,可能是指退出时做相应的清理工作)。要了解更多的
信息,请参见wait命令。
    debug [[-now] 0|1]
  
控制Tcl调试器以步进方式执行语句,设置断点等等。在没有参数的情况下,如果调试器没有运行,返回1,否则返回0。用1做参数时,启动调试器,用0做
参数时,停止调试器。如果连同-now一起使用的话,调试器将立即启动(也就是说,在debug命令当中)。否则调试器会在执行下一条语句的时候启动。
    调试命令不会改变任何的traps。可以参见以-D选项启动Expect(参见上面)
    要了解更多关于debugger的内容,请参见README文件和下面的SEE ALSO。
    disconnect
从终端关闭与一个克隆进程的连接,但让它在后台继续运行。这个进程将被赋予为单独的进程组(如果可能的话)。标准I/O被重定向到/dev/null。下面的代码使用disconnect命令使脚本在后台继续运行。
    if [fork]!=0 exit
        disconnect
    下面的脚本需要读取一个密码,然后每小时执行一次,每次执行的时候都要求输入密码。脚本提供了所需的密码,所以你只需输入一次就可以了。(参见能关闭回显的终端命令)。
    send_user "password?\ "
        expect_user -re "(.*)\n"
        for {} 1 {} {
            if [fork]!=0 {sleep 3600;continue}
               disconnect
               spawn priv_prog
               expect Password:
               send "$expect_out(1,string)\r"
               . . .
               exit
        }
用这种方式,而不是用Shell后台方式来执行程序的好处是,用disconnect可以在关闭前保存终端参数,然后把它们应用于新的终端中。如果使用&的话,Expect没有机会读取终端参数,因为在Expect取得控制权的时候,终端已经退出了。
    exit [-opts] [status]
  
使Expect退出或是准备退出。-onexit选项使下一个参数做为退出的句柄被使用。没有参数时,返回当前的退出句柄。-noexit选项使
Expect准备退出,而不是把控制权暂时返还给系统。用户定义的退出句柄和Expect内部的句柄都是以同样的方式被返回。接下来将不再执行
Expect命令。这在Tcl扩展环境下执行Expect时非常有用。保留当前的解释器(在Tk环境中的主窗口)以清除其他的Tcl扩展。如果
Expect再次调用exit(这有可能发生),不会返回句柄。退出时,全部连接将关闭,关闭的动作会被监测的进程检测为“到文件尾”。exit只按照正
常exit(2)的中的语句来执行,不会引发其他的动作。因此监视的进程如果没有检测到“到文件尾”的话,会继续执行。(能检测更多的情况是很重要的。例
如:什么样的信号会发给监测进程,但这些是由系统决定的,它们放在exit(3)的文档中)。如果被监测的进程继续运行的话,将会被init继承。当前的
状态信息将做为Expect的退出信息返回(如果没有指明的话,返回信息为0)。退出命令在脚本程序执行的最后才自动隐含的调用。
    Exp_continue [-continue_timer]
    这个命令可以使expect继续执行而不是正常的返回.默认情况下,exp_continue会重高超时时钟,-continue_timer选项会阻止时钟重新计数(连续计数).
    Exp_internal [-f file] value
  
如果是value非零的话,使接下来的命令将调试信息输出到Expect和标准错误输出.如果是0的话,输出的信息将会被屏蔽.调试信息包括收到的每条
信息和每次尝试用当前输出与脚本中的模式相匹配的信息.如果设置了输出文件,那么正常的和调试的信息都会被写到这个文件当中.(忽略上面value选项的
值).任何之前打开的调试输出文件将会被关闭.-info选项使exp_internal返回最近关于non-info参数的描述.
    Exp_open [args] [-I spawn_id]
    它返回对应于原始spawn
id的文件描述符.这样这个文件描述符就可以被使用了,就好像这个文件是被Tcl的open指令打开的一样.(这个spawn
id将不再使用,wait指令将不能用在这个进程.).-leaveopen选项使spawn id保持打开,以便供Expect命令使用.
    Exp_pid [-i spawn_id]
    它将返回对应于当前被跟踪进程的ID.如果使用-i选项,将返回对应于指定的spawn id的进程ID.
    Exp_send
        它是send的别称
    Exp_send_error
        它是Send_error的别称
    Exp_send_log
        它是Send_log的别称
    Exp_send_tty
        它是Send_tty的别称
    Exp_send_user
        它是Send_user的别称
    Exp_version [[-exit] version]
它用于确保脚本程序与当前的Expect兼容。在没有参数的情况下,返回当前Expect的版本.这个版本就会编译到脚本中.如果你确切的知道你的脚本程
序不需要最新版本的特性,可以指定一个以前的版本。   
  
版本号由三个由句点分隔的数字组成.第一个是主序号.对应某一主序号版本的Expect写的脚本程序,在不同主序号版本的Expect环境下基本不能正
常运行.exp_version在主版本不同的情况下会返回一个错误.第二个数字是次版本号.编写脚本的Expect的次版本号如果比当前的Expect
大的话,可能会用到一些新的特性,在当前的环境下可能不能正常运行.exp_version会在当主序号相同,但次序号比当前Expect版本大的时候返
回一个错误信息.第三个数字在Expect的版本比较中没有多大作用.它只是当发行版有任何变化的时候会增加.比如说增加一些新的文档或是做了优化.当升
级到一个新的次版本号时,这个数字会被初始化为零.如果使用了-exit选项,Expect会在当前的版本过期的时候打印一个错误信息,然后退出.
    expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]
    等待直到被监视进程的输出与设定的模式相匹配,或是一个指定的时间过后,或是遇到文件尾.如果最后的body是空的,那么它将被忽略.最近的
expect_before设定的模式会在其他模式之前被隐含地使用.最近的expect_after设定的模式将在所有其他模式匹配完后才被调用.如果
整个Expect命令的参数超过一行,这个参数可能被分为多行,各行之间用一个”\”连接,以防被分开解释.在这种情况下,Tcl解释器通常会置换掉”
\”.如果一个模式设定为eof.则相应的语句被在当达到文件尾的时候执行.如果一个模式设定为timeout,那么相应的语句会在超时时执行.如果没有
设定timeout对应的执行语句,将会在timeout时隐含执行空指令.即不执行任何语句.默认的超时时钟设的是10秒,但可以自己设定.通过
”set timeout30”,可以将超时时钟设定为30秒.如果设定为-1的话,那么超时时钟将是无穷大,如果一个模式设定为default,那么相应的语句将会在遇到文件尾
或是超时时执行.如果触发了相应的模式,则此模式对应的语句将会被执行.Expect返回语句执行的结果(或是在没有模式触发的情况下是空字符串).在多
种模式匹配的情况下,第一个匹配的模式对应的语句将被执行.
  
每次出现新的输出的时候,它们都会依次匹配相应的模式.因此,如果你想测试匹配是否成功,可以把最后一个模式设定为肯定会出现的东西,例如一个提示符.
在没有提示符的情况下,你需要使用一个timeout模式。模式被定义为三种类型.默认情况下,模式被定义为Tcl的string
match(字符串匹配)指令.(这些模式很像C
Shell中的正则表达式,它们通常被用来做模糊匹配).-gl选项保护那些可能被认为是Expect的选项的模式匹配字符串。以”-”开头的所有模式匹
配字符串都需要这样保护起来。(因为默认情况下,以”-”开头的字符串都被保留起来做为将来的选项)。例如:下面的代码期望一个正确的登录.(注意下面的
abort是一个已经在脚本的其他位置定义好的函数)
        expect {
                     busy               {puts busy\n ; exp_continue}
                     failed             abort
                     "invalid password" abort
                     timeout            abort
                     connected
                 }
  
在第四行需要使用引号,因为它包含了一个空格.如果不用引号把模式括起来的话,它会被分别解释为模式与执行函数.执行同样动作的其他模式同样需要把执行
函数的名称写出来(像其他两个执行”abort”函数的模式),如果使用regexp-style模式的话(看下面的例子),更多关于建立glob-
style模式的信息请参见Tcl手册.regexp模式以-re开头.上面的例子可以用regexp模式改写成下面的代码:
        expect {
                     busy       {puts busy\n ; exp_continue}
                     -re "failed|invalid password" abort
                     timeout    abort
                     connected
                 }
两种类型都可以被正确匹配。这就是说设置的类型可以不用是整个字符串。可以只匹配头部或是尾部(就假设其他部分也匹配一样)。用^来匹配字符串头部。
用$来匹配字符串尾部。如果你不希望等待直到字符尾,你可以在监视进程回显字符的中间时刻结束响应。虽然仍能打印出正确的结果,但最后的输出可能看上去有
点混乱。因此如果能够详细描述预期的字符串尾部的话,还是鼓励使用$来匹配尾部。在许多编辑器中,^和&分别表示首行和尾行。因为Expect不
是基于行缓冲的程序。所以这两个字符分别用来表示当前匹配缓冲区中的头数据和尾数据。-ex使模式进行精确匹配。这时,不对*,^等字符进行解释(但还是
要遵守Tcl的规则)。Expect patterns are always unanchored.
  
-nocase选项使输出中的大写字符也按小写字符匹配。模式匹配字符串本身改变。在读取输出进行匹配时,超过2000字符将会强制将前面的字符丢弃。
这个数目可以通过match_max来改变。(但太大的数目会降低匹配的效率)。如果patlist是full_buffer,则在收到
match_max个字节而没有相应的模式匹配成功时,执行full_buffer所对应的语句。不管是否使用了关键字full_buffer,丢弃的字
符都会被写到expect_out缓冲区中。如果patlist是关键字null。并且空是有效字符(通过remove_nulls指令访问),如果输出
是一个单个的ASCII码0,那么null相对应的语句将被执行。通过glob或是regexp模式是不能来匹配0字符。        
在匹配字符串时(或是遇到文件尾,或是缓冲区满full_buffer),任何匹配的或是前面没有匹配的输出都会被保存在expect_out缓冲区中。
匹配到的9个字符分别被放到expect_out(1,string)至expect_out(9,string)中。如果在模式前使用了
-indices选项,那么,这10个字符的开始字符和结尾字符在字符串中的位置被分别存放在变量expect_out(X,start)和
expect_out(X,end)中。其中X是自然数(应该是0到9)。0(expect_out(0,*))是指整个匹配的字符串,它可以用于
glob模式,也可以用于regexp模式。例如:如果一个进程的输出为“abcdefgh\n”,那么expect
“cd”的执行结果和下面的代码执行结果是一样的。
        Set    expect_out(0,string) cd
        Set    expect_out(buffer) abcd
“efgh\n”被丢弃到输出缓冲区了。如果一个进程的输出是”abbbcabkkkka\n”,那么expect –indices –re “b(b*).*(k+)”的执行结果和下面语句的执行结果是相同的。
        set expect_out(0,start) 1
                 set expect_out(0,end) 10
                 set expect_out(0,string) bbbcabkkkk
                 set expect_out(1,start) 2
                 set expect_out(1,end) 3
                 set expect_out(1,string) bb
                 set expect_out(2,start) 10
                 set expect_out(2,end) 10
                 set expect_out(2,string) k
                 set expect_out(buffer) abbbcabkkkk
“a\n”被丢弃了输出缓冲区中了。含有”*”(和-re
“.*”)的模糊匹配的模式会清空输出缓冲区,不再读取从进程中输出的字符。一般情况下,匹配的输出会被Expect的内部缓冲区丢弃.可以通过在模式前
加上-notransfer选项来避免被丢弃.这个选项在实验时非常有用(为了方便,可以简写成-not).与匹配输出相对应的spawn
id被存储在expect_out(spawn_id)中.
    -timeout 选项使得Expect使用选项后面的数值做为超时时间,而不是timeout变量中设置的时间.   
  
默认情况下,设定的模式只与当前进程的输出进行匹配.-i选项使得指定spawn_id或是spawn_id列的输出与下面列出的所有模式进行匹配(直
到下一个-i选项为止).spawn_id列要么是用空格分隔的一列spawn_id,要么是用变量存储的这要一列spawn_id.例如,下面的例子
中,当前进程与”connected”进行匹配,由变量$proc2指定进程与”busy”,”failed”,”invalid
passowrd”进行匹配。
        expect {
                     -i $proc2 busy {puts busy\n ; exp_continue}
                     -re "failed|invalid password" abort
                     timeout abort
                     connected
              }
  
全局变量any_spawn_id的值是在当前expect中所有-i选项定义的spawn_id进程列的总和.它用来使这些spawn_id进程列与
模式进行匹配。在一些-i选项中可能只给出了spawn_id列,但没有给出相应匹配模式.(例如,-i选项紧接下来就是另一个-i选项).那么这些
spawn_id列将会去匹配与any_spawn_id相对应的模式.   
    -i选项还可以定义一个全局变量,里面存储着spawn_id列.当变量内容发生变化时,它会被重新读取.这样就可以在程序执行的时候改变I/O源.以这种方式提供的spawn_id被称为”indirect spawn_id”.
  
Break和continue使流程(例如:for结构,proc函数)按照正常的顺序执行.exp_continue使expect继续执行而不是像
通常一样返回.这对于避免explicit
loops(不执行以后有语句,直接进入下一次循环)和重复的语句很有用.下面的例子是一个自动rlogin的代码片断.exp_continue的使用
避免了在rlogin揭示输入密码的时候的再写一个重复的expect语句.(需要等待第二次提示)
        expect {
                     Password: {
                         stty -echo
                         send_user "password (for $user) on $host: "
                         expect_user -re "(.*)\n"
                         send_user "\n"
                         send "$expect_out(1,string)\r"
                         stty echo
                         exp_continue
                     } incorrect {
                         send_user "invalid password or account\n"
                         exit
                     } timeout {
                         send_user "connection to $host timed out\n"
                         exit
                     } eof {
                         send_user \
                             "connection to host failed: $expect_out(buffer)"
                         exit
                     } -re $prompt
                 }
  
例如,下面的代码使用户可以在任务完全自动化的情况下,还能引导人机交互.这种情况下,终端被设置成原始状态.如果按下”+”,那么一个变量的值增加,
如果按下”P”,那么向进程发送几个回车符,或是以其它的方式回应一下.如果按下”i”,那么用户就会从脚本那儿把控制权收回,来与进程进行交互.在每个
情况下,exp_continue都使在执行完当前的动作之后,继续执行模式匹配.
    stty raw -echo
                 expect_after {
                     -i $user_spawn_id
                     "p" {send "\r\r\r"; exp_continue}
                     "+" {incr foo; exp_continue}
                    "i" {interact; exp_continue}
                     "quit" exit
                 }
    默认情况下,exp_continue会重置超时时间.如果以带有-continue_timer选项的方式执行exp_continue的话,超时时钟不会重新启动.
    Expect_after[expect_args]
    它和expect_before的工作方式相同.在expect和expect_after能同时匹配的情况下.进程与expect命令下面的模式进行匹配.想了解更多的信息请参见expect_before.
    Expect_background [expect_args]
  
它和expect有一样的参数列表.但不同的是它是立即返回.一旦有新的输入到达时就开始进行模式匹配,timeout和default两个模式对于
expect_background来说没有意义,它们会被隐含忽略.否则,expect_background会像expect一样调用
expect_before和expect_after的模式匹配.
  
当expect_background在执行模式匹配时,对应于这个spawn_id的后台进程将被阻塞.当执行完成时,后台进程被解开.在后台进程被
阻塞期间,还可以在前台以同样的spawn_id执行一个expect脚本.但在非阻塞情况下是不可能这样做的.在用同一个spawn_id声明一个新的
expect_background时,前一个就会被自动删除.声明一个没有匹配模式的expect_background将会使相应的spawn_id
失去在后台匹配模式的能力.
    Expect_before [expect_args]
  
它和expect具有相同的参数列表.但不同的是它立即返回.相同spawn_id最近的expect_before下的匹配模式会自动隐含的加载到下
面的expect命令中.如果其中一个模式匹配成功了,就好像匹配的模式是列在expect命令本身下面一样.如果expect_before和
expect的模式同时匹配,那么将使用expect_before.如果没有相应的匹配列出来,那么这个spawn_id将不进行任何模式匹配的动作.
  
除非使用-i选项强制声明,否则expect_before的模式将与执行expect_before命令时对应的spawn_id的进程输出进行匹配
(而不是有模式匹配成功时的spawn_id).-info选项会返回当前模式的详细信息.默认情况,它会报告当前的spawn_id的信息。也可以通过
指定spawn_id来显示指定spawn_id的信息.
例如:    expect_before –info –I $proc
    这样最多返回一个spawn_id的详细信息. The flag -indirect suppresses direct spawn ids that come only from indirect specifications.
    -all选项使expect_before报告所有spawn_id的信息,而不是单个spawn_id的信息。
    expect_tty [expect_args ]
  
和expect的用法很像,但它是从/dev/tty读取字符串(例如:用户的击键)。默认情况下,读是工作在精加工缓冲模式下的。因此,每行之后必须
以回车结尾,这样expect才能分别识别它们。读模式(例如行缓冲,等等)可以通过stty命令更改(参见下面的stty命令)
    expect_user [expect_args]
  
和expect的用法很像,但它是从stdin(标准输入)读取字符串(例如:用户的击键)。默认情况下,读是工作在精加工模式下的。因此,每行之后必
须以回车结尾,这样expect才能分别识别它们。读模式(例如行缓冲,等等)可以通过stty命令更改(参见下面的stty命令)。
    Fork
  
创建一个新进程。这个新进程是当前进程的完整拷贝。成功时,会返回0给新进程,返回新进程的ID给当前进程。失败时(失败的原因可能是资源匮乏,如交换
分区,内存不足等),返回一个-1给当前进程,没有新进程创建。复制的新进程和它的父进程一样通过exit命令退出。复制的新进程允许写日志文件。如果不
屏蔽大多程序的debugging(调试)和logging(写日志)功能,结果(个人认为:输出结果或是日志)看起来会显得有点混乱。在多个用户的情况
下,即使是很短暂的pty执行结果,看起来也会很让人混乱迷惑。因此,在监视某个进程(个人认为是执行spawn)之前执行fork更好一点。
    interact [string1 body1] ... [stringn [bodyn]]
  
返回当前进程的控制权给用户。所以击键会被传给当前进程(就像平时操作一样)。当前进程的stdout和stderr也会返回(个人认为:可能在脚本执
行时,标准输出和标准错误输出是被重定向到Expect的,因为执行spawn之后,expect会等待进程的输出,包括错误输出)。String-body被指定为参数。在这种情况下,当有指定的string输入时,对应的body就会被执行(默认情况,string不会被传给当前进程)。如果没有最后的body部分,那么将执行interact命令。如果整个interact语句参数过长,超过一行,这些参数会用反斜线连接,分隔在多行,这样避免了语句在执行时被隔断。这种情况下,在Tcl进行语法解释的时候会忽略这些反斜线,把这多行做为一条语句来执行。例如,下面的代码举例说明了以string-body方式执行interact命令。String-body是这样设定的:当你按下Ctrl+Z时,Expect将挂起,按下Ctrl+A时,用户将会看到屏幕显示“you typed a control A”,并且也向当前进程发送一个Ctrl+A。当用户按下$时,用户会看到屏幕上显示系统日期。按下Ctrl+C时Expect将退出。如果输入”foo” ,用户将在屏幕上看到“bar”,如果输入~~,那么Expect解释器交互执行。
        set CTRLZ \032
                 interact {
                     -reset $CTRLZ {exec kill -STOP [pid]}
                     \001   {send_user "you typed a control-A\n";
                             send "\001"
                            }
                     $      {send_user "The date is [exec date]."}
                     \003   exit
                     foo    {send_user "bar"}
                     ~~
                 }
    在string-body中,字符是按string在string-body中出现的顺序匹配的。
  
在不清楚余下的字符是什么的情况下,只是部分匹配的字符是不会被发送到当前进程的。如果在获得了余下的字符之后,整个字符串没有相应的string-
body可以匹配(也就是说整个字符串在string-body中,没有对应相同的string),除了上面说的匹配字符外,也没有其他更多的匹配(个人理解:比如整个字符xxxbbccada.第一次提到的匹配字符xxxbb,string-body中有两个对应的string:string1=xxxbb,string2=xxxbbcc,那么也就是说整个字符是没有相应的string与之匹配,如果只有string1,没有string2,那也就是“没有更多的匹配”,只有xxxbb会发送到当前进程,如果存在string2,那么我们最好把string2放在string1前面,这样可以先在匹配string2,如果输出字符串中,没有相应的xxxbbcc,然后再去匹配string1。也就是说把“最大匹配”放在前面),那么只有匹配的字符会发给当前进程。因此,我们可以把“部分匹配”放在后面,如果整个字符(或是“最大字符”)匹配失败,我们再进行“部分匹配”。默认情况下,string匹配必须是精确完全匹配。(与之相反,expect命令默认使用glob-style模式)。
-ex选项保证那些可能被解释成interact选项的string能被正确执行。任何以”-”开头的string都需要使用-ex。(所有以”-”开头的字符将被做为选项)
    -re选项强制string按regexp模式解释。这种情况下,像expect会把它的输出存储在变量expect_out里面一样,interact匹配的字符串也会在存储在变量interact_out中。-indices选项的作用也和expect中的一样。Eof模式列出了在遇到文件尾的时候要执行的语句。一个单独的eof模式可能跟在-output选项后面,这样当写输出遇到文件尾的时候,就会触发eof模式,执行相应的语句。默认的eof行为是返回,所以执行interact命令时,在遇到文件尾就是返回。Timeout模式介绍了超时(以秒为单位)的概念,并列出了(超时)连续数秒没有读取到字符后的执行语句。Timeout作用于最近指定的进程。**这里没有默认的timeout,特殊变量timeout(expect命令里面使用的)对这里的timeout模式没有影响。**例如,下面的命令可以用于自动退出用户,他们在一小时之内没有输入任何字符,却一直收到系统消息。
interact -input $user_spawn_id timeout 3600 return –output  $spawn_id
    如果模式为关键词null,而且null是允许的(通过remove_null命令),则在输出中如果出现单个的ASCII
0,那么null对应的语句将被执行。在glob和regexp模式下是不可能完成的。在模式前加上-iwrite选项,将会把匹配成功(或是遇到文件
尾)的进程的spawn_id赋值给变量interact_out(spawn_id)。Break和continue会使控制结构(for循环,子函数
等等)按照正常的方式运行,但return会使interact把信息返回给它的调用函数。Inter_return会使它的调用函数返回。例如,如果一
个子函数foo调用了inter_return,在执行inter_return时,子函数foo会返回。(这就是说,当interact交互式调用解释
器时,如果输入return,那么交互还将继续,如果输入inter_return,那么interact将返回)
    在interact执行过程中,终端工作在“原始状态”下,这样所有字符都将发送给当前进程。如果当前进程没有捕获到工作流程的信号,那么按下
Ctrl+Z会使其中止。如果想重启这个进程,可以给它发送一个“继续”信号(如执行:"kill  -CONT
"),如果你真想给当前进程发送一个“中止”信号,你可以考虑先监视csh,然后再启动你的程序。也就是说,如果你想发送中止信号
给Expect,首先要调出解释器(可能是按一下ESC键),然后按下Ctrl+Z。
  
为了避免进入解释器,交互式的执行命令,string-body可以用做“速记”,当string-body对应的body执行的时候,使用的前一个终
端模式。为了程序的执行效率,默认情况下,终端使用原始状态。-reset使终端恢复到interact执行以前的状态(总是“精加工”状态)。注意的
是,在进行终端模式转换的时候,此时输入的字符可能丢失(在一些系统上,会出现这种
糟糕的现象)。最好在你必须使用”精加工”模式再使用-reset选项。-echo选项使与模式进行匹配的字符同时也被发送给产生这些字符串的当前进程,就好像是当前进程读取到他们一样。这在当用户希望在执行某些指令需要看到回显的时候非常有用。
  
如果回显了一个模式,但最终没有匹配成功,这些字符会被发送到监视的进程,如果监视的进程再把它们显示出来的话,那么用户将会看到他们两次。-echo
可能仅仅适合于当用户不可能不完成模式匹配的情况。例如:下面是摘自于rftp,一个递归式ftp脚本,用户被提示输入”~g,~p,~l”,以便递归的
”获得,上传,查看”当前路径。这些字符和常规的ftp命令相差太远,用户除非出错,否则基本上不会打出”~”后面跟有某些字符的情况。这种情况下,他们
就可能会忽略了正确的结果。
        interact {
                     -echo ~g {getcurdirectory 1}
                     -echo ~l {getcurdirectory 0}
                     -echo ~p {putcurdirectory}
                 }
    -nobuffer选项会把进行模式匹配的字符发送给输出进程,就像这些字符是被读取的一样。这在你想让进程回显模式的时候非常有用。例如,下面的代码监视了哪个用户在拨叫(一种Hayes模式的Modem),每次都会在脚本的日志文件中后面看到一个”atd”。
        proc lognumber {} {
                     interact -nobuffer -re "(.*)\r" return
                     puts $log "[exec date]: dialed $interact_out(1,string)"
                 }
                 interact -nobuffer "atd" lognumber
  
在交互过程中,log_user的前一个值被忽略了。特别需要说明的是,interact会强制使他的输出记录成日志(输出到标准输出),因为它认为用
户不希望没有任何回应的交互。-o选项使下面的key-body模式应用于当前进程的输出(也就是说用当前进程的输出来匹配模式)。这对于处理像”在一个
telnet会话中输入很多错误字符(个人认为:非命令或是选项字符)”的情况非常有用。
  
默认情况下,interact希望用户对标准输入进行写操作,对标准输出进行读操作。-u选项通过指定进程名(通常是指定一个spawn_id)来使此
进程的用户与其他进程进行interact(交互)。这就使两个毫不相差的进程通过这样一个联系连接起来。为了协助调试,Expect的调试信息经常会输
出到标准错误输出(或是是标准输出,为了记录日志和调试信息)。同样,解释器也会交互的从标准输入读取字符。例如:下面的代码,建立了一个登录进程,它呼
叫用户,然后使双方连接在一起。当然其他进程也可以取代这里的login进程。一个脚本,允许在不提供用户名与密码的情况下正常工作。
        spawn login
                 set login $spawn_id
                 spawn tip modem
                 # dial back out to user
                 # connect user to login
                 interact -u $login
  
为了发送输出给多个进程,必须使用-output选项指定spawn_id列表。同样,要给多个进程输入字符,需要使用-input选项(-input
和-output,还有expect中的-i选项都支持列表,除了特殊变量any_spawn_id在interact命令中无效,在expect中有
效)。
  
所有接下来的选项或字符串(或模式)对当前的输入有效。直到下一个input选项为止。如果没有-input选项,-output选项暗含表示”–
input $user_spawn_id
–output”(在不含有-input选项的模式中也一样)。如果指定了一个-input选项,那么它将覆盖$user_spawn_id,如果出现第
二个–input选项,那么它将覆盖$spawn_id,还有可能会指定更多的-input选项。
  
这两个暗含的输入进程把它们的输出默认分别把$spawn_id和$user_spawn_id作为它们的输出(做了调换)。如果-input选项后面
没有-output,那么这个进程的输入将会被忽略。-i选项介绍了一种当没有使用-input或是-output选项时的替代方式。-i选项暗含一个
-o选项。
    使用“间接”spawn_id列可以改变交互进程 (“间接”spawn_id列已经在expect命令里面讲过) 。“间接”spawn_id列可以通过-i,-u,-input或是-output选项指定。
    interpreter  [args]
    使用户交互的输入Expect或是Tcl命令,每个命令的结果都会被打印出来。
  
Break和continue会使控制结构(for循环,子函数等等)按照正常的方式运行,但return会使interact把信息返回给它的调用函
数。Inter_return会使它的调用函数返回。例如,如果一个子函数foo调用了inter_return,在执行inter_return时,子
函数foo会返回。其他命令使interpreter继续提示输入新的命令。默认情况下,提示包含两个整数。第一个表示the depth of
evaluation stack嵌套的层数(也就是Tcl_Eval被调用了多少次)。第二个参数是Tcl的history
identifier历史指针。提示符可以通过定义一个叫做”prompt1”的子函数来设置,这个子函数的输出会成为下一个提示符。如果一条语句中包含
半开的(也就是一个,不是一对儿)引号,大括号,中括号或是小括号,那么下一个提示符会被放在新一行。第二个提示符同样也可以通过定义一个叫做
”prompt2”的子函数来设置。在interpreter执行过程中,终端使用“精加工”模式,即使它的调用函数使用的是“原始中”模式。如果在没有
使用-eof选项的情况下,标准输入被关闭,那么interpreter就会返回。如果使用了-eof选项,那么将调用下一个参数。
    log_file [args] [[-a] file]
  
如果指定了文件名,那么log_file命令会把会话的记录写入文件(从执行这条语句开始),如果没有给定任何参数,那么log_file命令会停止记
录。前面的日志文件都将被关闭。不指定文件名,还可以通过-open或是-leaveopen选项来指定Tcl文件描述符,这和spawn命令的用法一样
(参见spawn命令)。-a选项强制把log_user命令产生的输出记录到日志。默认情况下,为了在一次会话中能很方便的多次关闭日志记
录,log_file命令会把输出信息添加到文件尾,而不是覆盖原来的内容。如果想覆盖原来的内容,可以使用-noappend选项。-info选项使
log_file命令返回关于最近的non-info(非info选项)参数的描述。
    log_user -info|0|1
    默认时,send/expect对话会被记录到标准输出中,可以通过log_user 0来禁止,通过log_user 1来恢复。输出到日志文件维持不变。-info选项使log_user命令返回关于最近的non-info(非info选项)参数的描述。
    match_max [-d] [-i spawn_id] [size]
  
这个命令定义Expect内部使用的缓冲区大小。如果没有参数,返回当前大小。如果使用-d选项的话,将缓冲区设置为默认大小(初始的默认大小是
2000 Bytes)。如果使用了-i选项,那么设置的是对应于spawn_id的进程的缓冲区大小。否则设置的是当前进程的。
    overlay [-# spawn_id] [-# spawn_id] [...] program [args]
    终止当前的Expect程序,执行program
args。一个连字符没有指定参数,那么连字符将被放到命令之前,就像它是一个登录Shell一样。除了那些在命令行中做为参数指定的spawn_id
外,其他将全部被关闭。这些在命令行中指定的spawn_id将被重定向到指定的文件描述符。这些spawn_id被重定向到文件描述符是为了新程序来继
承。例如,下面的命令运行chess程序,而且允许当前程序--chess master(chess控制者)来控制。
        overlay -0 $spawn_id -1 $spawn_id -2 $spawn_id chess
    虽然它牺牲了执行程序化交互的能力,因为Expect已经失去控制权,但还是要比”interact –u”更有效率。注:在这里,没有提供控制终端,因此,如果你断开或是重定向了标准输入,那么控制作业的程序(Shell,login等等)将不能正常访问。
    parity [-d] [-i spawn_id] [value]
    定义parity是否需要与当前监视的进程的输出分隔开。如果设为0,则是分隔开,否则将不分开。如果没有参数的话,将返回当前值。-d选项将
parity设置为默认的值(初始默认值为1,不分开)。-i选项用来指定需要设置parity值的,对应于spawn_id的进程。否则设置当前进程的
parity值。
    remove_nulls [-d] [-i spawn_id] [value]
    此命令用来定义null在匹配模式或是存储到变量expect_out或是interact_out之前,是否需要与监视进程的输出分隔开。如果设为 1,则分开,如果为0,则不;




一些有用的expect脚本

autoexpect:这个脚本将根据自身在运行时用户的操作而生成一个expect脚本。它的功能某种程度上类似于在Emacs编辑器的键盘宏工具。一个自动创建的脚本可能是创建自己定制脚本的好的开始。

================================================
实用工具:autoexpect
=================================================
如果自己懒得写expect代码,则可以用autoexpect生成。autoexpect工具是用expect写成的一个工具脚本,它可以录制你执行的操作、命令、键盘输入等等,之后自动生成expect脚本。
autoexpect脚本代码见:http://blog.sina.com.cn/s/blog_5432f2730100vcqn.html
使用方法:
1、把上面链接里的autoexpect代码保存成文件:autoexpect.exp
2、执行下面命令进行录制:
[root@localhost ~]# expectautoexpect.exp -p
 说明:执行完上面命令后就可以进行你需要的操作了,需要结束录制时,用exit退出即可。
3、录制完后,会在当前目录生成一个script.exp文件,这个文件就是录制好的expect脚本了。是直接拿来使用,还是再改改,或是学习用,就看你自己的需要了。
kibitz:这是一个非常有用的工具。通过它两个或更多的用户可以连接到同一个shell进程。

tkpasswd: 这个脚本提供了修改用户密码的GUI工具,包括可以检查密码是否是基于字典模式。这个工具同时是一个学习expect和tk的好实例。



参考文献:

http://fanqiang.chinaunix.net/a4/b8/20010912/1000001278.html

http://bbs.chinaunix.net/thread-594417-1-1.html

http://www.xmydlinux.org/201109/607.html

http://expect.sourceforge.net/

另附:

python的参考文献:

http://duplicity.nongnu.org/epydoc/duplicity.pexpect-pysrc.html

http://www.ibm.com/developerworks/cn/linux/l-cn-pexpect2/

http://www.ibm.com/developerworks/cn/linux/l-cn-pexpect1/