Los administradores y técnicos de sistemas se encuentran a menudo con la ingrata tarea de realizar aburridas tareas de mantenimiento o prevención en los incontables aparatos que están bajo su responsabilidad.
A menudo es fácil realizar un fichero de comandos, bien directamente en el interprete de comandos Bourne (la shell de toda la vida), bien de forma mas elaborada en Perl o Phyton, que nos permite automatizar este tipo de trabajos, y así dedicarnos a otras actividades mas creativas.
Sin embargo a menudo nos encontramos con aplicaciones de configuración interactivas que no permiten este tipo de solución. Seguramente habéis intentado inyectar comandos directamente desde un fichero desviando la entrada estándar, pero esta solución, aparte de burda y poco elegante, no siempre da los resultados apetecidos:
Esto a veces nos obliga a repetir en numerosas ocasiones tediosas sesiones interactivas para configurar un encaminador, determinar el estado de sistemas vitales para el funcionamiento de la red, conectarse a un determinado servidor, etc.
Si sufrís a menudo estas penalidades, y estáis buscando una solución sencilla a este tipo de problemas, Expect es la herramienta que necesitáis. Seguramente algunos recordareis Crosstalk, un programa de comunicaciones que permitía automatizar conexiones serie, a base de esperar ciertos mensajes por el puerto y responder de forma apropiada en función de lo recibido.
Pues bien Expect funciona de forma similar y además se puede aplicar a toda clase de aplicaciones interactivas con presentación de tipo textual, incluyendo programas semigraficos basados en curses (lamentablemente los programas de tipo gráfico no tiene cabida en Expect ;-( ).
Expect se apoya en el lenguaje de comandos extensible Tcl, y por tanto puede parecer necesario aprender otro lenguaje de comandos mas. Tal vez seria la mejor forma de exprimir sus posibilidades, pero os puedo asegurar que yo lo uso sin saber apenas nada de tcl (estoy contento con Perl y no me apetece cambiar).
Veamos un sencillo ejemplo del uso de Expect (no, no es el Hola Mundo!). Pongamos que tenemos que conectarnos muy a menudo con un determinado servidor de ficheros ftp y situarnos en un directorio concreto para después ejecutar una serie de comandos. A mano tendríamos que teclear unos cuantos comandos, con expect la cosa quedaría en uno único.
El programa (ftp_1.exp) seria el siguiente:
#!/usr/bin/expect -f
#
#################################################################
#
# este parte se comentara mas adelante, de momento insertala al
# principio de cada fichero de comandos.
#
set force_conservative 1 ;# set to 1 to force conservative mode even if
;# script wasn't run conservatively originally
if {$force_conservative} {
set send_slow {1 .001}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}
#################################################################
#
spawn ftp localhost
expect -exact "Name (localhost:root): "
send -- "ftp\r"
expect "Password:"
send -- "barreiro@arrakis.es\r"
expect -exact "ftp> "
send -- "binary\r"
expect -exact "ftp> "
send -- "hash\r"
expect -exact "ftp> "
send -- "cd pub/spain/gnome\r"
log_user 1
expect -exact "ftp> "
send -- "ls\r"
expext -exact "ftp> "
send -- quit\r"
expect eof
exit
Veamos el significado de los comandos mas importantes de este programa:
spawn... ejecuta la aplicación a controlar
expect... escucha la salida de la aplicación y espera la cadena indicada
send... envía a la aplicación la cadena indicada, '\r' corresponde a la pulsación de la tecla 'Retorno'
expect eof normalmente expect recibe un eof al terminar el comando lanzado con spawn. exit termina la ejecucion del programa expect
El programa lanza en primer lugar el comando 'ftp' y queda a la espera de la peticion de nombre de usuario. Una vez que se recibe se envia 'ftp'. Se queda ahora a la espera de la peticion de password, y se envia esta al recibirla. Una vez que llega el indicador de 'ftp', se envia los comandos deseados de forma succesiva.
Para terminar se ejecuta el comando 'exit' termina el programa expect