Don Libes' Expect: A Surprisingly Underappreciated Unix Automation Tool (2016)
blog.robertelder.org
blog.robertelder.org
https://metacpan.org/pod/distribution/Expect/Expect.pod
The regex matching features of the Perl version make it extremely useful to match and extract interactive results.
Here are some examples:
Check the IP address of the localhost
>ifconfig
<192\.168\.1\.1
>ip -6 addr show
<2001:db8::f00d
ssh to a remote host
>ssh root@host-021
<assword:
>>secret_password
# issue a command once logged in
>ls
>exit
[1] - http://expect-lite.sourceforge.net/I was using Tcl mostly running on Windows, and the Expect library for some reason had tremendous lag, or maybe it was a paid extension from ActiveState, I can’t remember the exact reason for not using it...
So I decided to just reimplement my own ‘expect’ command using native Tcl and a socket with just enough knowledge of Telnet control codes to get a prompt to appear.
What amazed me was how few lines of code it took to implement a fully functional Expect, and how useful it was as a means of structuring the automation, specifically around timing when to send inputs, parsing outputs, and confirming an action completed.
I’ll try to dig up the old code and post it on Github...
I can’t think of much I’d use it for today. Ansible is far better.
It was mostly helpful when you had to deal with a mainframe terminal program that was otherwise impossible to automate.
When you need "expect", it's wonderful.
And if you are going for solid production, you probably want to re-implement "expect" anyway -- so all input is whitelisted and unexpected messages are flagged. You probably don't what to break your expensive 1990's industrial device because you were driving it with expect script, and it cheerfully ignored "WARNING RESERVE BATTERY DEAD, REPLACE BEFORE POWER OFF" messages.
* to deploy commercial software whose configuration is only through an interactive terminal session and stored in an undocumented binary format
* to drive gdb to inspect a suspect Red Hat 6 "will not fix" GUI component that can go into an "impossible" pure cpu loop, to determine whether to kill it or whether it's busy in a more benign state.
Edit: the deploy is invoked by ansible, whose own expect module recommends the real expect "for complex cases"Edit: and Guile
- to deploy commercial software whose configuration is only through an interactive terminal session and stored in an undocumented binary format
- to drive gdb to inspect a suspect Red Hat 6 "will not fix" GUI component that can go into an "impossible" pure cpu loop, to determine whether to kill it or whether it's busy in a more benign state.
> most of the things that you could use expect for, are usually done much better using another method.
Outside of it's very narrow use case (driving un-scriptable CLIs and automated tests for command-line tools, and maybe some exotic CLI-centered workflows), trying to use "expect" will often result in fragile code with surprising failure mode.
In 2nd example, script will fail if user has non-default top's config. It also messes up terminal on exit. Use top's "personal configuration file" instead.
In the 4th example, you are not just trapping Ctrl-D in bash, you are trapping it in all bash-spawned commands (like "cat >file"). I am going to guess that bash's native IGNOREEOF option was what the author wanted.
In the 9th example (md5sum) , expect'll work fine -- but learning standard unix commands like "grep -m1" and/or "tee /dev/stderr" will allow many things that expect cannot, like doing an md5sum on millions of small files.
Good times.
I used Expectk extensively in 1993, but I can't say I really enjoyed it. It was a crufty and error-prone undertaking, and in my opinion is best for testing, or as a last resort for talking to black-box code with an interactive cli.
I've thought about going back to the developers of the packages, asking them to provide workarounds based on environment variables, etc. I may still do this, but it seems like Expect might provide a handy workaround in the meanwhile.
However, I'm concerned that the mock-GUI dialogs that these packages use (using terminal graphics) might make it hard for Expect to interact with them. For example, some of these dialogs want the user to navigate through a menu, select an item, etc.
Suggestions, anyone?