'''Expect Hints and Tips''' describes tricks of the trade when using [Expect]. ** See Also ** [Stubsification of Expect]: [Secure expect]: ** Sending Special Characters ** This is how you send ctrl+C through expect: send \003 ** Unambiguous Commands ** Because of the potential for name conflicts in the global namespace, [[send] command is also available as [[exp_send], a longer name which is less likely to conflict with other package commands. Likewise, various other Expect commands are also available via longer names. When working with an extended Tcl, such as Tk, it's often necessary to use the longer names, since, for example, Tk has its own [send] command If Expect had been written for ten-year-old Tcl, rather than being the first extension ever discovered, it of course would rely on namespaces to avoid name conflicts." ** Proper Use of `exp_close` and `exp_wait` ** [D. J. Hagberg] rightly writes, "Here's the BIG RULE for Expect: Every `exp_spawn` requires a call to `exp_close` *and* `exp_wait`." [RJ] 2007-06-21: Yeah, I don't know. I've only ever ran across a single issue that required an `exp_close`/`exp_wait` to deal with it. That was a script that was testing how many processes I could spawn before running into memory problems on a [Solaris] station. I ran out of [pty%|%ptys] first, and that hung the [X%|%Xserver] and dumped a huge core file. But I've never needed to close/wait - the script exits and the processes go away, unless you loop a spawn command too many times. I've never seen that in a real-use script, aside from [multixterm]. [PYK] 2014-07-16: `exp_wait` is more often needed than `exp_close`, but neither is strictly necessary if a script is finished and happy to let the spawned program receive an [eof%|%EOF] signal when the script exits. The most common [gotcha] is that the user doesn't foresee the Expect script ending and the spawned program getting prematurely killed. In this case, `exp_wait` is usually what's wanted, and if the spawned program isn't going to end on its own accord, maybe also `exp_close`. Another way to make sure the spawned program runs to completion is to `expect` the special pattern `eof`, perhaps after setting `$timeout` to `-1`. This is probably far more common than using `exp_wait` or `exp_close`. ** Expect Variables Set in Local Scope ** Expect commands have the interesting feature that they look for Expect such as `$timeout` first in the local scope, and then in the global scope. However, when an Expect command is called from within a procedure, any Expect variables that command sets are set in the local scope. For example, if `spawn` is called within a procedure, `$spawnid` will be set in that procedure. There are various ways to work under these circumstances, but the most common is to add, e.g. `global spawnid` to the procedure that calls `spawn` ** Alternatives to Expect ** When programmatic access to some facility is available, it is often preferable to driving a command-line program with Expect: [ssh]: [ftp]: from [tcllib] [http]: from [tcllib] [smtp]: from [tcllib] Note: FTP sends passwords in clear text, so be sure to first build a secure tunnel and use FTP over that. See [CL]'s notes on [http://phaseit.net/claird/comp.unix.programmer/ftp_automation.html%|%FTP automation]. Likewise, make sure not to send e-mail passwords as plain text, either. ** Configuring ** [CL] recently mentioned on comp.lang.tcl that expect has a $HOME/.expectrc file that can be used to predefine procs, variables, etc. that one uses regularly. ** Terminal Setting ** `$TERM` must be set correctly in the environment. In one case the terminal was [http://www.gnu.org/software/screen/%|%screen], but `$TERM` was set to `xterm`, causing unexpected results. Setting it to `screen` solved the problem. ** Debugging ** To turn on messages from Expect that help explain what it is doing: ====== exp_internal 1 ====== ** Embedding in a Shell Script ** '''[PYK] 2016-08-02''': When embedding an Expect script in a shell script, for a more legible script that also correctly handles values that contain whitespace, pass arguments on the command line instead of interpolating them into the Expect script. For example, instead of this: ======none #! /usr/bin/env sh expect <> Expect