2009-10-08 9 views
17

Necesito automatizar el registro en una sesión de TELNET usando espero, pero tengo que ocuparme de múltiples contraseñas para el mismo nombre de usuario.Uso de instrucciones condicionales dentro de 'esperar'

Aquí está el flujo Necesito crear:

  1. sesión TELNET abierto a una IP
  2. Enviar nombre de usuario
  3. Enviar contraseña
  4. contraseña incorrecta? Enviar el mismo nombre de usuario nuevo, entonces una contraseña diferente
  5. Debería haber iniciado la sesión en el éxito en este punto ...

Por lo que vale la pena, esto es lo que tengo hasta ahora:

#!/usr/bin/expect 
spawn telnet 192.168.40.100 
expect "login:" 
send "spongebob\r" 
expect "password:" 
send "squarepants\r" 
expect "login incorrect" { 
    expect "login:" 
    send "spongebob\r" 
    expect "password:" 
    send "rhombuspants\r" 
} 
expect "prompt\>" { 
    send_user "success!\r" 
} 
send "blah...blah...blah\r" 

No hace falta decir que esto no funciona, y tampoco se ve muy bonito. De mis aventuras con Google espera parece ser algo así como un arte oscuro. Gracias de antemano a cualquier persona por su ayuda en el asunto!

+0

He agregado más información a mi respuesta. – tvanfosson

Respuesta

31

Tiene que recomendar el libro Exploring Expect para todos los programadores esperables - invaluable.

He reescrito el código: (no probado)

proc login {user pass} { 
    expect "login:" 
    send "$user\r" 
    expect "password:" 
    send "$pass\r" 
} 

set username spongebob 
set passwords {squarepants rhombuspants} 
set index 0 

spawn telnet 192.168.40.100 
login $username [lindex $passwords $index] 
expect { 
    "login incorrect" { 
     send_user "failed with $username:[lindex $passwords $index]\n" 
     incr index 
     if {$index == [llength $passwords]} { 
      error "ran out of possible passwords" 
     } 
     login $username [lindex $passwords $index] 
     exp_continue 
    } 
    "prompt>" 
} 
send_user "success!\n" 
# ... 

exp_continue bucles de nuevo al principio del bloque de esperar - es como una declaración "rehacer".

Tenga en cuenta que send_user termina con \n no \r

Usted no tiene que escapar el carácter > en su mensaje: no es especial para Tcl.

-1

Si conoce los identificadores de usuario y las contraseñas, entonces también debe saber qué pares de ID de usuario/contraseña están alineados con qué sistemas. Creo que sería mejor mantener un mapa de qué par de ID de usuario/contraseña va con qué sistema luego extraer esa información y simplemente usar la correcta.

Por lo tanto - ya que, obviamente, no le gusta mi consejo, entonces le sugiero que busque en el wikipedia page y poner en práctica un procedimiento que devuelve 0 si tiene éxito y 1 si los tiempos de expectativa a cabo. Eso le permitirá detectar cuándo falló la contraseña suministrada, la esperanza de espera se agotó y volver a intentar. Si esto es útil, puedes eliminar tu voto negativo ahora que lo he editado.

En retrospectiva, es probable que desee hacer esto junto con el mapa de todos modos, ya que es posible que desee detectar un inicio de sesión fallido si se cambia la contraseña.

+0

Lo siento por el voto en negativo.Estaba en una larga llamada y quería una forma rápida de mostrar que aún no tenía una respuesta sin escribir una publicación para explicar por qué. De todos modos, ciertamente no usaría el método condicional si tuviera una forma confiable de documentar las contraseñas que se usan en ciertos dispositivos. Puede cambiar a través de revisiones de firmware fuera de mi control, así que todo lo que puedo hacer es tener una lista de contraseñas lista para probar. Entiendo lo que tengo que hacer, usar una declaración condicional y actuar sobre la respuesta, simplemente no sé cómo hacerlo. :) – shuckster

+0

Puede eliminar el voto ahora que he editado, es decir, si la información adicional es útil o al menos no hace que la publicación sea inútil. Siempre que no acepte una respuesta, es probable que la gente continúe agregando respuestas, aunque es posible que desee actualizar su pregunta con la información sobre por qué es difícil hacer un seguimiento de las contraseñas. – tvanfosson

10

Con un poco de golpes encontré una solución. Resulta que esperar que utiliza una sintaxis TCL que no estoy del todo familiarizado con:

#!/usr/bin/expect 
set pass(0) "squarepants" 
set pass(1) "rhombuspants" 
set pass(2) "trapezoidpants" 
set count 0 
set prompt "> " 
spawn telnet 192.168.40.100 
expect { 
    "$prompt" { 
    send_user "successfully logged in!\r" 
    } 
    "password:" { 
    send "$pass($count)\r" 
    exp_continue 
    } 
    "login incorrect" { 
    incr count 
    exp_continue 
    } 
    "username:" { 
    send "spongebob\r" 
    exp_continue 
    } 
} 
send "command1\r" 
expect "$prompt" 
send "command2\r" 
expect "$prompt" 
send "exit\r" 
expect eof 
exit 

espero que esto sea útil para otros.

+1

Utilicé una solución similar para SSH pero leí las contraseñas de un archivo de contraseñas '~/.ssh/ssh-passwords'. El nombre de host y el nombre de usuario se leen desde mi archivo '~/.ssh/config'. Así que ejecutando: '[cssh] (https://github.com/DavidGamba/bin/blob/master/cssh) server1' se expandirá a [email protected] – DavidG

+0

Soy nuevo en esperar, lo esperado {"case1 "{...}" case2 "{...}" case3 "{...}}, ¿es este algún tipo de declaración de mayúsculas y minúsculas como C++? gracias –

+0

@ B.Mr.W. sí, usarlo en el exterior '' '{}' '' básicamente hace que sea una caída en vez de declaraciones '' 'if''' individuales – eulerworks

Cuestiones relacionadas