UNIX FAQ Version 2.1 92/12/04 -- Question 3.9

UNIX FAQ Version 2.1 92/12/04 -- Question 3.9

How do I run 'passwd', 'ftp', 'telnet', 'tip' and other interactive programs from a shell script or in the background?

These programs expect a terminal interface. Shells makes no special provisions to provide one. Hence, such programs cannot be automated in shell scripts. The 'expect' program provides a programmable terminal interface for automating interaction with such programs. The following expect script is an example of a non-interactive version of passwd(1). # username is passed as 1st arg, password as 2nd set password [index $argv 2] spawn passwd [index $argv 1] expect "*password:" send "$password\r" expect "*password:" send "$password\r" expect eof expect can partially automate interaction which is especially useful for telnet, rlogin, debuggers or other programs that have no built-in command language. The distribution provides an example script to rerun rogue until a good starting configuration appears. Then, control is given back to the user to enjoy the game. Fortunately some programs have been written to manage the connection to a pseudo-tty so that you can run these sorts of programs in a script. To get expect, email "send pub/expect/expect.shar.Z" to library@cme.nist.gov or anonymous ftp same from durer.cme.nist.gov. Another solution is provided by the pty 4.0 program, which runs a program under a pseudo-tty session and was posted to comp.sources.unix, volume 25. A pty-based solution using named pipes to do the same as the above might look like this: #!/bin/sh /etc/mknod out.$$ p; exec 2>&1 ( exec 4<out.$$; rm -f out.$$ <&4 waitfor 'password:' echo "$2" <&4 waitfor 'password:' echo "$2" <&4 cat >/dev/null ) | ( pty passwd "$1" >out.$$ ) Here, 'waitfor' is a simple C program that searches for its argument in the input, character by character. A simpler pty solution (which has the drawback of not synchronizing properly with the passwd program) is #!/bin/sh ( sleep 5; echo "$2"; sleep 5; echo "$2") | pty passwd "$1"