Next Previous Contents

3. Lo basico de Expect

A continuacion iremos ampliando las posibilidades del ejemplo presentado en el primer capitulo, al tiempo que aprendemos mas acerca de la sintaxis de los comandos de expect.

3.1 El comando Expect

El programa anterior funcionara siempre que la conexion al servidor de ftp sea correcta. Pero que pasa por ejemplo si esta falla (ftp_21)?

Cuando la conexion falla, ftp presentara un determinado mensaje de error. El comando expect puede gestionar distintos mensajes de una forma similar a una sentencia case (ftp_31).


expect -exact {
  "connection refused" {puts "Conexion denegada\n";exit}
  "Host name lookup failure" {puts "servidor desconocido\n";exit}
  "Name" 
} 

Y si no se recibe ninguno de estas cadenas, ya sea la esperada o cualquiera de los errores conocidos (ftp_22)?.

Para este caso tenemos la opcion generica 'timeout'. Si expect no recibe ninguna de las cadenas esperadas en el un tiempo determinado (10sg por defecto), se ejecuta lo indicado en la opcion 'timeout' (ftp_32).


expect -exact {
  timeout {puts "El programa ha temporizado\n";exit}
  "connection refused" {puts "Conexion denegada\n";exit}
  "Host name lookup failure" {puts "servidor desconocido\n";exit}
  "Name" 

} 

Por supuesto el valor de la temporizacion se puede variar en cualquier momento a lo largo del programa, e incluso anularse si se la asigna el valor -1.


set timeout 15
set timeout -1

3.2 Los patrones regulares

Otra cosa que salta a la vista en los ejemplos anteriores es que escribir las cadenas que espera el comando expect, puede llegar a ser una tarea ardua y tediosa. Para ayudarnos en esta tarea se puede recurrir a los patrones regulares, que nos permitiran contruir estas cadenas mas facilmente usando caracteres comodin. Expect permite usar dos sintaxis para contruir los patrones regulares:

El primero es de sintaxis muy sencilla, pero menos flexible. El segundo es utiliza la misma sintaxis que el comando grep.

explicacion de los tipos de patrones (solo tabla).

Con los comodines tambien podemos solventar el problema que plantean aplicaciones en las que el indicador cambia durante la ejecucion, en ejecuciones succesivas o al cambiar de usario o sistema.

exact glob regexp

[a-z] [a-z] cualquier caracter entre a y z

[^a-z] [^a-z] cualquier caracter que no este entre a y z

? . un caracter cualquiera

* .* un numero cualquiera de caracteres

^ ^ el principio de la cadena

$ $ el final de la cadena

\[ \\\[ \\\[ carcater corchete

\* \\\* caracter *

. \. caracter .

Aqui telnet_1.exp Aqui algunos ejemplos de patrones tipicos.

3.3 Controlando la presentacion

En los ejemplos anteriores podemos observar que todo el texto de salida , tanto el de respuesta de los comandos como la simulacion de entrada de usuario, aparece en la pantalla. Esto puede ser apropiado durante las pruebas iniciales, pero excesivo y confuso para el uso cotidiano. La presentacion de mensajes de respuesta de los comandos se puede eliminar usando la variable 'log_user'. (ftp_51.exp)


log_user 0        elimina los mensajes de respuesta de los comandos
log_user 1        activa la presentacion de respuestas

Si, una vez eliminada totalmente la presentacion, queremos enviar mensajes informando al usuario del progreso del programa, podemos hacerlo con el comando (ftp_52.exp) :


send_user "mensaje\n"

3.4 Paso de parametros a los programas Expect.

Expect recibe los parametros en la variable 'argv' (ftp_61.exp)

Podemos acceder a cada una de las variables de la matriz argv usando la siguiente sintaxis:

[lindex $argv n] parametro n (recordar que el primer elemeto de la matriz es 0)

Tambien podemos asignar los parametros a variables:

set sistema [lindex $argv 0]

Y podemos saber el numero de parametros usando la variable:

$argc

De esta forma podemos controlar facilmente el paso de parametros a los programas:


if $argc<2 {
  send_user "$argv0: faltan parametros\n"
  exit
} 
set sistema [lindex $argv 0]
set usuario [lindex $argv 1]
send_user "$sistema\n"
send_user "$usuario\n"
send_user "[lindex $argv 0]\n"
send_user "[lindex $argv 1]\n"

3.5 El comando Send

Del comando send no hay mucho que contar, simplemente recordar incluir el doble guion para que no interprete parte de la cadena como una opcion propia:


send -- "...."

Y no olvidar terminar los comandos enviados al programa con un retorno de carro, o el caracter que necesite la aplicacion:


send -- "get fichero.tgz \r"

3.6 el comando spawn

Este comado inicia la ejecucion de la aplicacion controlando su entrada y salida.

Se pueden lanzar varias aplicaciones simultaneamente, controlando a traves de la variable spawn id cual de ellos atiende a los comandos expect y send.

3.7 el comando interact

Con el comando 'interact' podemos enviar un primer grupo de comandos de forma automatica, recuperar despues el control sobre la aplicacion para enviar ordenes de forma manual, y finalmente terminar la ejecucion nuevamente de forma automatica (ftp_71.exp).


send_user "Entro en modo interactivo. Pulsa 'escape' para continuar\n"
interact "escape" return
send_user "Vuelvo al modo automatico\n"
...


Next Previous Contents