|
Home | Switchboard | Unix Administration | Red Hat | TCP/IP Networks | Neoliberalism | Toxic Managers |
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and bastardization of classic Unix |
Recommended Links | Reference | Telnet simulation in Perl | Expect.pm | |||
VNC | Screen | Python expect module | Admin Horror Stories | Unix History | Humor | Etc |
|
Expect is a great tool in a system administrators arsenal and can be used to easily automate tasks that require periodic user input. This can allow the administrator to make better use of their time than watching the application or utility to spot the next time it requires input.
|
For example Expect is a uniquely powerful tool for automating interactive applications such as telnet and ftp. For the same reason expect is also useful for testing interactive applications. And by adding Tk, you can also wrap interactive applications in X11 GUIs. Expect can make easy all sorts of tasks that are prohibitively difficult with anything else. You will find that Expect is an absolutely invaluable tool - using it, you will be able to automate tasks that you've never even thought of before - and you'll be able to do this automation quickly and easily. Expect - Expect - Home Page -- an extremely interesting page of Don Libes the famous author of Expect. Here is a short history of Expect:
Expect was conceived of in September, 1987. The bulk of version 2 was designed and written between January and April, 1990. Minor evolution occurred after that until Tcl 6.0 was released. At that time (October, 1991) approximately half of Expect was rewritten for version 3. See the HISTORY file for more information. The HISTORY file is included with the Expect distribution.
Around January 1993, an alpha version of Expect 4 was introduced. This included Tk support as well as a large number of enhancements. A few changes were made to the user interface itself, which is why the major version number was changed. A production version of Expect 4 was released in August 1993.
In October 1993, an alpha version of Expect 5 was released to match Tcl 7.0. A large number of enhancements were made, including some changes to the user interface itself, which is why the major version number was changed (again). The production version of Expect 5 was released in March '94.
In the summer of 1999, substantial rewriting of Expect was done in order to support Tcl 8.2. (Expect was never ported to 8.1 as it contained fundamental deficiencies.) This included the creation of an exp-channel driver and object support in order to take advantage of the new regexp engine and UTF/Unicode. The user interface is highly but not entirely backward compatible. See the NEWS file in the distribution for more detail.
There are important differences between Expect 3, 4, and 5. See the CHANGES.* files in the distribution if you want to read about the differences. Expect 5.30 and earlier versions have ceased development and are not supported. However, the old code is available from http://expect.nist.gov/old.
The Expect book became available in January '95. It describes Expect 5 as it is today, rather than how Expect 5 was when it was originally released. Thus, if you have not upgraded Expect since before getting the book, you should upgrade now.
Historical notes on Tcl and Tk according to John Ousterhout
I got the idea for Tcl while on sabbatical leave at DEC's Western Research Laboratory in the fall of 1987. I started actually implementing it when I got back to Berkeley in the spring of 1988; by summer of that year it was in use in some internal applications of ours, but there was no Tk. The first external releases of Tcl were in 1989, I believe. I started implementing Tk in 1989, and the first release of Tk was in 1991.
Among other things it contains rscript 1.0 which is based upon Expect/Tcl and allows you to automate remote logins and execute remote commands, somewhat like rsh.
The site also contains many valuable examples. Among them are multixterm, kibitz, rftp (recursive ftp), passmass, autoexpect. Here are man pages for some of the examples:
There are many interesting papers about expect. Among them:
|
Switchboard | ||||
Latest | |||||
Past week | |||||
Past month |
June 13, 2007 | Musings
TCL (Tool Command Language, typically pronounced as "tickle") is a scripting language created by John Ousterhout in 1988 while working at the University of California, Berkeley. To provide additional functionality, TCL supports extensions. One of the most popular extensions is Expect which is a tool developed by Don Libes for automating and testing interactive applications such as ftp. telnet and ssh.I assume you know how to generate SSH keys using ssh-keygen and understand that if you want to be able to ssh to a remote system without entering a password you need to create the keys without a passphrase. Once the private and public keys are generated the public key have to be copied to the the user account on the remote system that you wish to have access to and added to the remote users authorized_keys file. Typically scp or ftp is used for that task followed by ssh'ing to the remote system and then doing something like the following:
$ mkdir .ssh $ chmod 700 .ssh $ cd .ssh $ touch authorized_keys $ chmod 600 authorized_keys $ cat ../id_dsa.pub >> authorized_keys $ rm ../id_dsa.pub
Alternatively you can use the ssh-copy-id script to do all the above work for you. This is an interactive script that requires you to the enter the remote user's password and possibly enter yes to add your local host to the remote user's known_hosts file.Here is a simple shell script which automates the generation of DSA keys with no passphrase for a user and transfers the public DSA key to a remote system using expect. Basically it is a wrapper around ssh-keygen and ssh-copy-id.
001 002
003004
005006
007008
009010
011012
013014
015016
017018
019020
021022
023024
025026
027028
029030
031032
033034
035036
037038
039040
041042
043044
045046
047048
049050
051052
053054
055056
057058
059060
061062
063064
065066
067068
069070
071072
073074
075076
077078
079080
081082
083084
085086
087088
089090
091092
093094
095096
097098
099100
101102
103104
105106
107108
109110
111112
113114
115116
117118
119120
121122
123124
125126
127128
129130
131132
133134
135136
137138
139140
141142
143144
145146
147148
149150
151152
153154
155156
157158
159160
161162
163164
165166
167168
169170
#!/bin/bash
#
# Copyright (c) Finnbarr P. Murphy 2006
#
# ---- start configurables ----
PATH=/usr/sbin:/usr/bin:/sbin:/bin
LOCALHOMEDIR=/home
# ----- end configurables -----
function
usage {
printf
"Usage: setupkeys -U remote-username -P remote-password -H remote-host -u local-username\n"
exit
2
}
# --- script starts here
echo
(( $
# == 0 )) && usage
(( $EUID != 0 )) && {
echo
"ERROR: You must be root to run this script."
exit
1
}
username=
""
password=
""
host=
""
localuser=
""
while
getopts
"u:P:U:H:"
OPTION
do
case
$OPTION
in
U) username=
"$OPTARG"
;;
P) password=
"$OPTARG"
;;
H) host=
"$OPTARG"
;;
u) localuser=
"$OPTARG"
;;
esac
done
# --- basic argument checking
if
[[ -z
"$username"
]];
then
echo
"ERROR - No username entered."
exit
1
fi
if
[[ -z
"$password"
]];
then
echo
"ERROR - No passed entered."
exit
1
fi
if
[[ -z
"$host"
]];
then
echo
"ERROR - No host entered."
exit
1
fi
if
[[ -z
"$localuser"
]];
then
echo
"ERROR - No localuser entered."
exit
1
fi
# --- do some sanity checking here
echo
-n
"Checking if $localuser in /etc/passwd. "
grep
"^$localuser:"
/etc/passwd
> /dev/null
2>&1
RESULT=$?
if
(( RESULT == 1 ));
then
echo
;
echo
"ERROR - $localuser not found in /etc/passwd."
exit
1
fi
echo
"Yes"
echo
-n
"Checking connectivity with $host. "
/bin/ping
-q -c 2 $host > /dev/null
2>&1
RESULT=$?
if
(( RESULT == 1 ));
then
echo
;
echo
"ERROR - could not ping $host."
exit
1
fi
echo
"System is alive."
# --- check for $localuser public and private ssh keys
# --- we need to be $localuser here when using ssh-* utilities
echo
-n
"Checking for $localuser ssh key files. "
SSH_KEYS_FOUND=0
if
[[ -d $LOCALHOMEDIR/$localuser ]];
then
if
[[ -s $LOCALHOMEDIR/$localuser/.
ssh
/id_dsa
&& -s $LOCALHOMEDIR/$localuser/.
ssh
/id_dsa.pub ]];
then
sudo
-u $localuser -- /usr/bin/ssh-keygen
-e -f $LOCALHOMEDIR/$localuser/.
ssh
/id_dsa.pub |
grep
"1024-bit DSA"
> /dev/null
2>&1
RESULT=$?
if
(( RESULT == 0 ));
then
SSH_KEYS_FOUND=1
fi
fi
fi
if
(( SSH_KEYS_FOUND == 1 ));
then
echo
"Found"
else
echo
"Not found"
rm
-rf $LOCALHOMEDIR/$localuser/.
ssh
mkdir
$LOCALHOMEDIR/$localuser/.
ssh
chmod
700 $LOCALHOMEDIR/$localuser/.
ssh
chown
-R $localuser:$localuser $LOCALHOMEDIR/$localuser/.
ssh
sudo
-u $localuser -- /usr/bin/ssh-keygen
-q -t dsa -N
""
-f $LOCALHOMEDIR/$localuser/.
ssh
/id_dsa
echo
"New ssh key files generated (DSA protocol)"
fi
# --- add $localname's public key to $username@$host authorized keys
TMPUSER=expectscript-user.$$
cat
<<EOT
> $TMPUSER
#!/usr/bin/expect
if {[llength \$argv] != 4} {
puts "usage: \$argv0 localuser username password host"
exit 1
}
log_file -a expectscript-user.log
log_user 0
set localuser [lindex \$argv 0]
set username [lindex \$argv 1]
set password [lindex \$argv 2]
set host [lindex \$argv 3]
set timeout 60
spawn /usr/bin/ssh-copy-id -i \$localuser/.ssh/id_dsa.pub \$username@\$host
expect {
"assword: " {
send "$password\n"
expect {
"again." { exit 1 }
"expecting." { }
timeout { exit 1 }
}
}
"(yes/no)? " {
send "yes\n"
expect {
"assword: " {
send "$password\n"
expect {
"again." { exit 1 }
"expecting." { }
timeout { exit 1 }
}
}
}
}
}
exit 0
EOT
echo
-n
"Copying $localuser's public key to $host. "
chmod
755 $TMPUSER
sleep
3
./$TMPUSER $LOCALHOMEDIR/$localuser $username $password $host
RESULT=$?
rm
-f $TMPUSER
if
(( RESULT == 0 ));
then
echo
"Succeeded"
rm
-f expectscript-user.log
else
echo
"Failed"
echo
"ERROR: Check expectscript-user.log"
exit
1
fi
# we are done
echo
"Setup completed. Goodbye."
exit
0
You may have to modify it if you use a shell other than bash as I have only tested in on Linux systems. If you want to use RSA, it is easy to modify the script to generate RSA keys.
telnet login using expect
Posted by pgpatel (pgpatel), 29 July 2005 Hi,
I am trying to login into the remote system using expect code....I am new in expect...
my code is:#!/usr/bin/expect
spawn telnet 172.25.126.248
expect "login:"
exp_send "myname\r"
expect "password: "
exp_send "123456\r"
exitbut when i am executing this code it is asking for password and getting stuck(hang)...
can you please help me?
please give me regarding code....what is log_user 0
can u explain it please?thanks
Posted by pgpatel (pgpatel), 29 July 2005
Hello
i am able to login now but i am not getting pompt...
instead of it i am getting message like
plesae press<enter> to continue
or reenter your local terminal hostname
or oress esc to quit
please reply me
tnaks
Posted by Custard (Custard), 29 July 2005
Hi,The telnet protocol is slightly clever in that the client negotiates with the server what terminal type to use, and also sends other bits of vital information from the environment.
Since you are spawning telnet from within expect, these pieces of information don't appear to be available to send, so the telnet server (telnetd) is asking for them (or actually, probably the .profile script sees that they are not present and asks for them).
So, you could try setting the environment before spawning telnet, or handling the new prompt you have identified and sending the hostname to the server.
I haven't tested this, and I will have a play later, but this *looks* like what is happening.
hth
B
Posted by Custard (Custard), 29 July 2005
I had a little play, and made the following changes :-Code:
#!/usr/bin/expect
# Set the DISPLAY environment variable (as a test)
set env(DISPLAY) chilli:0
spawn telnet 172.25.126.248
# Not absolutely necessary, but good to keep the spawn_id for later
set telnet $spawn_id
# Case insensitive, just in case..
expect -nocase "login:"
send "myuser\r"
# My telnetd insisted on an uppercase P. This works bothways
expect -nocase "password: "
send "123456\r"
# Match the prompt (contains a $)
expect -re {\$}
# Get the environment variables
send "env\r"
# Wait for the prompt
expect -re {\$}
exit
Which should print out the environment variables available to the shell you are connecting to.
Compare these with the environment when you connect manually.
Mine seemed to get it right, with DISPLAY and TERM set correctly.
Maybe this test will show up something.Oh, and I forgot to ask, you are connecting to a Unix telnetd, right?
hth
B
Posted by pgpatel (pgpatel), 1 August 2005
Thanks for your reply....
now i got solution....
now i have one another question...
how can i save output of a particular command into file(log file)
suppose after login into remote shell i give the command ls -l (i.e. exp_send "ls -l\r")
then how can i save the result of that command in file...
i found some hint like logfile command
but i donot know how to use it...
thanks in advance
Posted by admin (Graham Ellis), 2 August 2005
I would simply exp_send an ls command with a redirect out to file.Alternative (if you want to analyse results as well) is to save the expect_out(buffer) array member to a file after you've done the ls.
Posted by pgpatel (pgpatel), 8 August 2005
Thanks for reply...
but i didnot get your answer...
can you explain me in detail with code as example please?
in my example i use ls as just example...in real i will use some other commands to get some system status...
thanks...
Posted by admin (Graham Ellis), 8 August 2005
Sample code that spawns a remote ping, grabs the text that comes back, and saves it to a file.Code:
#!/usr/bin/expect
log_user 0
spawn ping -c 3 www.wellho.net
expect eof
set rres [open got.txt w]
puts $rres $expect_out(buffer)
Expect is a venerable tool for scripting interactive command-line tools. One normally sees expect coupled with the TCL programming language -- for example, in the DejaGNU test environment. Expect-lite is a wrapper for expect designed to allow you to capture an interactive session more directly mapped into a script. The expect-lite language also includes simple conditionals and other programming language elements, and can be readily mixed with bash programming.Expect-lite is itself an expect script, so to use it you will need to install expect from your distribution's package repository. Once you have it installed, expand the expect-lite tarball and copy the expect-lite.proj/expect-lite file to somewhere in your $PATH and give it appropriate permissions.
# tar xzvf /.../expect-lite_3.0.5.tar.gz # cp expect-lite.proj/expect-lite /usr/local/bin # chown root.root /usr/local/bin/expect-lite # chmod 555 /usr/local/bin/expect-liteThe main goal of expect and expect-lite is to automate an interactive session with a command. I'll refer to the command that expect(-lite) is talking to as the spawned command. A basic expect(-lite) script might spawn a command, wait for the command to ask for some input, and send some data in response to that request.
In expect, the
send
command sends information to the spawned command, and theexpect
command is used to wait for the spawned command to send a particular piece of information. Normally there is a timeout set to handle the case where the spawned command does not provide the expected output within a given time; in other words, when the spawned program does not behave as planned by the expect(-lite) script.I'll use gdb as an example to demonstrate the difference between using expect and expect-lite to automate a simple interaction. Shown below is the code for a trivial C++ application and the start of a normal gdb debug session for this application.
$ cat main.cpp #include <iostream> using namespace std; int main( int, char** ) { int x = 2; x *= 7; cout << x << endl; return 0; } $ g++ -g main.cpp -o main $ gdb ./main GNU gdb Red Hat Linux (6.6-35.fc8rh) ... (gdb) br main Breakpoint 1 at 0x400843: file main.cpp, line 7. (gdb) r Breakpoint 1, main () at main.cpp:7 7 int x = 2; (gdb)The expect program below will automate the execution of the above program with gdb printing out the value of
x
at a point in the program execution.$ cat ./gdb-main-expect #!/usr/bin/expect spawn gdb ./main; send "br main\n"; expect "Breakpoint 1 at"; send "r\n"; expect "Breakpoint 1, main"; expect "(gdb)"; send "step\n"; expect "(gdb)"; send "step\n"; expect "(gdb)"; send "print x\n"; send "quit\n"; expect "Exit anyway"; send "y\n"; $ ./gdb-main-expect spawn gdb ./main br main GNU gdb Red Hat Linux (6.6-35.fc8rh) Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu"... Using host libthread_db library "/lib64/libthread_db.so.1". (gdb) br main Breakpoint 1 at 0x400843: file main.cpp, line 7. (gdb) r ... Breakpoint 1, main () at main.cpp:7 7 int x = 2; (gdb) step 8 x *= 7; (gdb) step 9 cout << x << endl; (gdb) print x $1 = 14 (gdb) quit The program is running. Exit anyway? (y or n) $The same automated interaction is expressed in expect-lite below. Notice that the quoting and other syntax is now missing and the expect-lite program is much closer to what a user would actually see and type. Lines starting with
>>
are things that expect-lite will send to the spawned command. Lines starting with<
are things that expect-lite will wait to see in the output of the spawned command.$ cat gdb-main-expect-lite.elt > gdb /home/ben/expect-lite-examples/main >>br main <Breakpoint 1 at >>r <Breakpoint 1, main >>step <(gdb) >>step <(gdb) >>print x >>quit <Exit anyway >>yExpect-lite was created primarily for running automated software tests. A side effect of this heritage is that any script execution requires the specification of the host where the test is to be executed. In the example below I have set up SSH to allow me to log in to the same user on localhost without a password, as detailed after the example. There should be no security implications with this. At the end of the expect-lite interaction you can see an overall result as passed, which is also due to expect-lite's primary purpose being software testing.
$ expect-lite remote_host=localhost cmd_file=gdb-main-expect-lite.elt spawn ssh localhost Last login: ... 2008 from localhost.localdomain $ bash ->Check Colour Prompt Timed Out! $ gdb /home/ben/expect-lite-examples/main br main ... (gdb) br main Breakpoint 1 at 0x400843: file main.cpp, line 7. (gdb) r Breakpoint 1, main () at main.cpp:7 7 int x = 2; (gdb) step 8 x *= 7; (gdb) step 9 cout << x << endl; (gdb) print x $1 = 14 (gdb) quit The program is running. Exit anyway? (y or n) y ##Overall Result: PASSThe below commands set up SSH to allow you to connect to the localhost without a passphrase. In this case the "elo" hostname is also available as a shortcut to connect using the correct SSH identity file. In the above session I could have used
expect-lite remote_host=elo cmd_file=...
to execute the command on localhost.$ mkdir -p ~/.ssh $ chmod 700 ~/.ssh $ cd ~/.ssh $ ssh-keygen -f expect-lite-key $ cat expect-lite-key.pub >> authorized_keys2 $ vi ~/.ssh/config Host localhost IdentityFile ~/.ssh/expect-lite-key Host elo HostName localhost IdentityFile ~/.ssh/expect-lite-key $ chmod 600 config $ chmod 600 authorized_keys2 $ ssh eloFor the gdb example I could not use the more normal
>
to describe what expect-lite should send, because the>
expect-lite command has some built-in logic to first detect a prompt from the spawned command.>>
on the other hand just sends what you have specified right now. The prompt detection logic in expect-lite did not detect the gdb prompt in the gdb-main-expect-lite.elt example above and so would time out waiting for a prompt from the spawned command.Expect-lite did not detect the gdb prompt because the regular expressions that it uses in
wait_for_prompt
did not handle that prompt format. One way to change that situation would be to customize those regular expressions in the expect-lite file if you are using expect-lite against gdb often. Because I was forced to use>>
to send data to gdb, I had to also include lines at some places which explicitly waited for gdb to send a prompt. If the prompt detection regular expressions can detect your prompts, then using the>
command to send data will make a less cluttered script, as you will not need to explicitly wait for prompts from the spawned program.You can assign values to variables by capturing part of the output of the spawned command. When your expect-lite script starts executing, the spawned command will be bash, so you can directly run programs by sending the command line to bash with the
>
expect-lite command. As seen above, if you execute an interactive program such as gdb, then the>
expect-lite command talks with gdb.The below script captures the output of the
id
command and throws away everything except the user name. The conditional expression in expect-lite has a similar syntax to that of a similar expression in C; the difference is that in expect-lite the IF portion is prefixed and terminated with a question mark and the separator between the THEN and ELSE statement is a double colon instead of a single colon. The reason that I wait for the final "..." at the last line of the script is so expect-lite will not close the session after issuing the echo command and before the results of echo are shown.$ id uid=777(ben) gid=777(ben) $ cat branches.elt >id +$user=[a-z]+=[0-9]+\(([a-z]+) ? $user == ben ? >echo "howdee ben..." :: >echo "A stranger eh?..." <...Expect-lite supports loops by using labels and jump to label together with conditionals. Because expect-lite starts a bash shell on the remote host, you can also use the shell's conditionals and looping support. Shown below is an expect-lite script that uses bash to perform a loop:
$ cat shell-conditionals.elt >for if in `seq 1 10`; do > echo $if >done >echo ... <...A caveat is that to get at shell variables from expect-lite you have to first
>>echo $bashvar
and then read it into an expect-lite variable with something like+$expectvar=.*\n
. For instance:$ cat pwd-test.elt >echo $PWD +$expectpwd=\n(.*)\n >echo $expectpwd... <...You can also directly embed expect code into an expect-lite script. This might come in handy if you already have some familiarity with expect and need to perform a more advanced interaction at some stage in the script. Expect-lite lines starting with
!
are embedded expect.Needing to specify the host name to expect-lite all the time requires a level of preparation work before one can start using expect-lite. The usage message for expect-lite informs you that you can set
Ben Martin has been working on filesystems for more than 10 years. He completed his Ph.D. and now offers consulting services focused on libferris, filesystems, and search solutionsEL_REMOTE_HOST
to define a default value for the host, but if you try this then you will discover thatexpect-lite/read_args{}
only works when passed two command-line arguments (version 3.0.5), so if you define a default host with the environment variable, you will need to pass a dummy argument to expect-lite in order for its argument parsing to allow script execution.
About:
Expect-lite is a wrapper for expect, created to make expect programming even easier. The wrapper permits the creation of expect script command files by using special character(s) at the beginning of each line to indicate the expect-lite action. Basic expect-lite scripts can be created by simply cutting and pasting text from a terminal window into a script, and adding '>' 'Release focus: Major feature enhancements
Changes:
The entire command script read subsystem has changed. The previous system read directly from the script file. The new system reads the script file into a buffer, which can be randomly accessed. This permits looping (realistically only repeat loops). Infinite loop protection has been added. Variable increment and decrement have been added to support looping.Author:
Craig Miller [contact developer]
Jul 31, 2007 | www.ibm.com/developerworks
If you manage systems and networks, you need Expect.
More precisely, why would you want to be without Expect? It saves hours common tasks otherwise demand. Even if you already depend on Expect, though, you might not be aware of the capabilities described below.
Expect automates command-line interactions
You don't have to understand all of Expect to begin profiting from the tool; let's start with a concrete example of how Expect can simplify your work on AIX® or other operating systems:
Suppose you have logins on several UNIX® or UNIX-like hosts and you need to change the passwords of these accounts, but the accounts are not synchronized by Network Information Service (NIS), Lightweight Directory Access Protocol (LDAP), or some other mechanism that recognizes you're the same person logging in on each machine. Logging in to a specific host and running the appropriate
passwd
command doesn't take long-probably only a minute, in most cases. And you must log in "by hand," right, because there's no way to script your password?Wrong. In fact, the standard Expect distribution (full distribution) includes a command-line tool (and a manual page describing its use!) that precisely takes over this chore.
passmass
(see Resources ) is a short script written in Expect that makes it as easy to change passwords on twenty machines as on one. Rather than retyping the same password over and over, you can launchpassmass
once and let your desktop computer take care of updating each individual host. You save yourself enough time to get a bit of fresh air, and multiple opportunities for the frustration of mistyping something you've already entered.The limits of Expect
This
passmass
application is an excellent model-it illustrates many of Expect's general properties:
- It's a great return on investment: The utility is already written, freely downloadable, easy to install and use, and saves time and effort.
- Its contribution is "superficial," in some sense. If everything were "by the book"-if you had NIS or some other domain authentication or single sign-on system in place-or even if login could be scripted, there'd be no need for
passmass
. The world isn't polished that way, though, and Expect is very handy for grabbing on to all sorts of sharp edges that remain. Maybe Expect will help you create enough free time to rationalize your configuration so that you no longer need Expect. In the meantime, take advantage of it.- As distributed,
passmass
only logs in by way oftelnet
,rlogin
, orslogin
. I hope all current developerWorks readers have abandoned these protocols forssh
, whichpassmasss
does not fully support.- On the other hand, almost everything having to do with Expect is clearly written and freely available. It only takes three simple lines (at most) to enhance
passmass
to respectssh
and other options.You probably know enough already to begin to write or modify your own Expect tools. As it turns out, the
passmass
distribution actually includes code to log in by means ofssh
, but omits the command-line parsing to reach that code. Here's one way you might modify the distribution source to putssh
on the same footing astelnet
and the other protocols:
Listing 1. Modified passmass fragment that accepts the -ssh argument...
} "-rlogin" {
set login "rlogin"
continue
} "-slogin" {
set login "slogin"
continue
} "-ssh" {
set login "ssh"
continue
} "-telnet" {
set login "telnet"
continue
...
In my own code, I actually factor out more of this "boilerplate." For now, though, this cascade of tests, in the vicinity of line #100 of
passmass
, gives a good idea of Expect's readability. There's no deep programming here-no need for object-orientation, monadic application, co-routines, or other subtleties. You just ask the computer to take over typing you usually do for yourself. As it happens, this small step represents many minutes or hours of human effort saved.
31 Jul 2007 | www.ibm.com/developerworks
If you manage systems and networks, you need Expect.
More precisely, why would you want to be without Expect? It saves hours common tasks otherwise demand. Even if you already depend on Expect, though, you might not be aware of the capabilities described below.
Expect automates command-line interactions
You don't have to understand all of Expect to begin profiting from the tool; let's start with a concrete example of how Expect can simplify your work on AIX® or other operating systems:
Suppose you have logins on several UNIX® or UNIX-like hosts and you need to change the passwords of these accounts, but the accounts are not synchronized by Network Information Service (NIS), Lightweight Directory Access Protocol (LDAP), or some other mechanism that recognizes you're the same person logging in on each machine. Logging in to a specific host and running the appropriate
passwd
command doesn't take long-probably only a minute, in most cases. And you must log in "by hand," right, because there's no way to script your password?Wrong. In fact, the standard Expect distribution (full distribution) includes a command-line tool (and a manual page describing its use!) that precisely takes over this chore.
passmass
(see Resources) is a short script written in Expect that makes it as easy to change passwords on twenty machines as on one. Rather than retyping the same password over and over, you can launchpassmass
once and let your desktop computer take care of updating each individual host. You save yourself enough time to get a bit of fresh air, and multiple opportunities for the frustration of mistyping something you've already entered.This
passmass
application is an excellent model-it illustrates many of Expect's general properties:
- It's a great return on investment: The utility is already written, freely downloadable, easy to install and use, and saves time and effort.
- Its contribution is "superficial," in some sense. If everything were "by the book"-if you had NIS or some other domain authentication or single sign-on system in place-or even if login could be scripted, there'd be no need for
passmass
. The world isn't polished that way, though, and Expect is very handy for grabbing on to all sorts of sharp edges that remain. Maybe Expect will help you create enough free time to rationalize your configuration so that you no longer need Expect. In the meantime, take advantage of it.- As distributed,
passmass
only logs in by way oftelnet
,rlogin
, orslogin
. I hope all current developerWorks readers have abandoned these protocols forssh
, whichpassmasss
does not fully support.- On the other hand, almost everything having to do with Expect is clearly written and freely available. It only takes three simple lines (at most) to enhance
passmass
to respectssh
and other options.You probably know enough already to begin to write or modify your own Expect tools. As it turns out, the
passmass
distribution actually includes code to log in by means ofssh
, but omits the command-line parsing to reach that code. Here's one way you might modify the distribution source to putssh
on the same footing astelnet
and the other protocols:
Listing 1. Modified passmass fragment that accepts the -ssh argument...
} "-rlogin" {
set login "rlogin"
continue
} "-slogin" {
set login "slogin"
continue
} "-ssh" {
set login "ssh"
continue
} "-telnet" {
set login "telnet"
continue
...
In my own code, I actually factor out more of this "boilerplate." For now, though, this cascade of tests, in the vicinity of line #100 of
passmass
, gives a good idea of Expect's readability. There's no deep programming here-no need for object-orientation, monadic application, co-routines, or other subtleties. You just ask the computer to take over typing you usually do for yourself. As it happens, this small step represents many minutes or hours of human effort saved.
An unreliable program can be controlled from a perl program using the Expect.pm module. A description of the unreliable program and the use of the Expect module is presented.I have a program that I need to run a large number of times. This program has a nasty bug in it. When you feed it bad data, it just sits there forever instead of providing a helpful error message. Bad Program!
I can't change the program, but I need to call this program inside a loop in my code. So I am using the perl Expect module to skip over the problem cases and continue with the rest of the runs of the program.
The Expect.pm module is capable of managing this process, so I wrote a few little test programs to help me understand how to accomplish this task. This document includes the tests along with a few words of explanation. For more documentation about the Expect module, search CPAN.
Oct 14, 2006 | The Sysadmins Secret Weapons
kibitz/xkibitz: Kibitz is a well-debugged script in the Expect scripting language that permits two people to interact inside a single session, and as such is perfect for remote expert-to-novice tutoring and assistance, multiple-author document editing, and technical support. Don Libes at NIST created it and put it into the public domain.
Rather like screen, kibitz includes the ability to scroll back sessions, save the entire session to screen, and even edit the session log while it's being recorded.
(Kibitz also makes possible multi-player text-type games, but don't tell the boss that.)
User alice kibitzes with user bob by typing:
kibitz bob
Alice now sees a new shell for her joint session with Bob, and Bob gets prompted as to how he can join the conversation (if he wishes). Either can exit by typing Ctrl-D or "exit".Alice can kibitz with Bob even if he's on host foo.bar.com by saying
kibitz [email protected]
Unfortunately, kibitz uses rshell (one of the insecure Berkeley r-commands) for this, but you can trick it into running over SSH using a command alias.xkibitz (expanded-kibitz) is an enhanced version that better supports multiple users coming and going from an ongoing kibitz session.
- Accumulates session log, which may be selectively played back.
- Facilitates real-time collaboration, even for document editing. "Type over the shoulder" of users, to help them.
- The kibitz interpreter is built using the "expect" language, which must be present on both hosts, as must tcl.
Automate your repetitive interactionsThe Expect language (an extension of Tcl/Tk, but other variations are also available) is used to write scripts that run sessions with interactive programs, as if the script were a user interacting directly with the program.
Expect scripts can save you a great deal of time, particularly when you find yourself engaging in repetitive tasks. Expect can interact with multiple programs including shells and text-based Web browsers, start remote sessions, and run over the network.
For example, if you frequently connect to a system on your local intranet to run particular program -- the
test-servers
command, for instance -- you can automate it with an Expect script namedservmaint
, whose contents appear in Listing 6.Listing 6. Sample Expect script to automate remote system program execution
#!/usr/bin/expect -f spawn telnet webserv4 expect "login:" send "joe\r" expect "Password:" send "secret\r" expect "webserv4>$" send "test-servers\r" expect "webserv4>$" send "bye\r" expect eof
Now, instead of going through the entire process of having to runtelnet
to connect to the remote system, log in with your username and password, run the command(s) on that system, and then log out. You just run theservmaint
script as given in Listing 6; everything else is done for you. Of course, if you give a password or other proprietary information in such a script, there is a security consideration; at minimum, you should change the file's permissions so that you're the only user (besides the superuser) who can read it.Any repetitive task involving system interaction can be programmed in Expect -- it's capable of branching, conditionals, and all other features of a high-level language so that the response and direction of the interaction with the program(s) can be completely automated.
Multixterm creates multiple xterms that can be driven together or separately. It can be used to login via SSH to multiple hosts and control them simultaneously, or for ad hoc things where you want to see the results as you type. Each xterm may also be driven separately. Multixterm is scriptable so that you can easily fire up, for example, a dozen xterms with a single command, tiled nicely on your screen. In addition to SSH, multixterm can drive rlogin, telnet, passwd, or any program that runs in an xterm.
Expect is a great tool in a system administrators arsenal and can be used to easily automate tasks that require periodic user input. This can allow the administrator to make better use of their time than watching the application or utility to spot the next time it requires input.
In the following example expect is used to automate the inputing of a password for a series of rsync commands tunneled through ssh.
The script automates a series of rsync operations using only the password for access to the remote host so that the security of the two machines is not reduced by making the source machine trust the destination machine in any way (for example .rhosts or a ssh key with an empty pass phrase).
The script reads a password from the user and then holds that password in a variable for use each time the ssh application that rsync is using as a tunnel asks for it.
The "stty -echo" prevents the password from being echoed to the screen when it is typed in and the "stty echo" turns it back on.
#!/usr/bin/expect -f spawn date expect "#" send_user "The password for HOSTNAME: " stty -echo expect_user -re "(.*)\n" {set PASSPH $expect_out(1,string)} send_user "\n" stty echo set timeout -1 spawn date expect "#" spawn rsync -ave ssh --numeric-ids HOSTNAME:/etc /sdc/ expect "password:" { send "$PASSPH\n"} expect "#" spawn date expect "#" spawn rsync -ave ssh --numeric-ids HOSTNAME:/admin /sdc/ expect "password:" { send "$PASSPH\n"} expect "#" spawn date expect "#" spawn rsync -ave ssh --numeric-ids HOSTNAME:/home /sdd expect "password:" { send "$PASSPH\n"} expect "#" spawn date expect "#" spawn rsync -ave ssh --numeric-ids HOSTNAME:/mail /sdd expect "password:" { send "$PASSPH\n"} expect "#" spawn date expect "#" spawn rsync -ave ssh --numeric-ids HOSTNAME:/work /sdc/ expect "password:" { send "$PASSPH\n"} expect "#" spawn date expect "#"(Submitted by Noel Mon Nov 17, 2003 )
Copyright 1999-2003 Noel Davis
All trademarks are the property of their owners.
All articles are owned by their author
RootPrompt.org
For example the following program runs rlogin to the named machine and then sets your DISPLAY to whatever it was on the source machine.
#!/depot/path/expect -- # xrlogin - rlogin but with current DISPLAY # # You can extend this idea to save any arbitrary information across rlogin # Don Libes - Oct 17, 1991. if {[llength $argv] != 1} { puts "usage: xrlogin remotehost" exit } set prompt "(%|#|\\$) $" ;# default prompt catch {set prompt $env(EXPECT_PROMPT)} set timeout -1 eval spawn rlogin $argv expect eof exit -re $prompt if [string match "unix:0.0" $env(DISPLAY)] { set env(DISPLAY) "[exec hostname].[exec domainname]:0.0\r" } send "setenv DISPLAY $env(DISPLAY)\r" interact
Hi,
I'm trying to login to a router using telnet and EXPECT, to backup the
router config.When I'm connecting to the device via telnet, everything is ok, but when I'm
using a perl/expect-Script to connect, the router asks "Press any key to
continue", even before the login prompt.*** via telnet commandline:
# telnet 1.2.3.4
Trying 1.2.3.4...
Connected to 1.2.3.4.
Escape character is '^]'.
One200Username:
*** via script# ./save-cpe.pl
Trying 1.2.3.4...
Connected to 1.2.3.4.
Escape character is '^]'.
One200Press any key to continue (Q to quit)
This is the perl code I spawn telnet with:
$telnet = Expect->spawn('telnet', $ipaddr)
or error_exit(11, "....");Looks like the router thinks the screen height is just a few lines?
Any ideas?
Thanks,
Re: "expect" spawns telnet -- screen height
> This is the perl code I spawn telnet with:
>
> $telnet = Expect->spawn('telnet', $ipaddr)
> or error_exit(11, "....");
>
> Looks like the router thinks the screen height is just a few lines?OK, I've found out that the following code works ok when run from a bash
shell:my $telnet = new Expect;
$telnet->raw_pty(1);
if (defined ($telnet->slave)) {
$telnet->slave->clone_winsize_from(\*STDIN);
}$telnet->spawn('telnet', $ipaddr)
or error_exit(11, ".....");Unfortunately, I'm running this script from a PHP Page, NOT from a bash
shell... perl teminates without any hint when reaching the line
"$telnet->slave->clone_winsize_from(\*STDIN);".Any Idea how to set the winsize to e.g. 80x25 without cloning it or where to
clone it from when run from a PHP script?
Re: "expect" spawns telnet -- screen height
My solution, based on Jens script, is not very elegant, but it works
from crontab (for example) :open TTY,"/dev/console" or die "not connected to a terminal\n";
$telnet->slave->clone_winsize_from(\*TTY);
close TTY;Daniel
--
dpratlong
Expect plays a crucial role in network management by Cameron Laird
passmass
, along with
all the rest of the
example tools and documentation standard for the latest Expect, is available
online. autoexpect
, exp_internal
,
and interact
, mostly-that are specific to Expect. Don Libes -- an extremely interesting page of the famous author of Expect
Rscript is based upon Expect/Tcl and allows you to automate remote logins and execute remote commands, somewhat like rsh.
Society
Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers : Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism : The Iron Law of Oligarchy : Libertarian Philosophy
Quotes
War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda : SE quotes : Language Design and Programming Quotes : Random IT-related quotes : Somerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose Bierce : Bernard Shaw : Mark Twain Quotes
Bulletin:
Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 : Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law
History:
Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds : Larry Wall : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOS : Programming Languages History : PL/1 : Simula 67 : C : History of GCC development : Scripting Languages : Perl history : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history
Classic books:
The Peter Principle : Parkinson Law : 1984 : The Mythical Man-Month : How to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite
Most popular humor pages:
Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor
The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D
Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.
This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...
|
You can use PayPal to to buy a cup of coffee for authors of this site |
Disclaimer:
The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.
Last modified: March 29, 2020