2009-03-25 11 views
17

Tengo un script de espera que se conecta a unos pocos enrutadores a través de ssh. Todos estos enrutadores tienen la misma contraseña (lo sé, está mal), y el script necesita conocer esa contraseña para poder conectarse a los enrutadores. Actualmente, la contraseña se pasa a mi secuencia de comandos como un argumento en la línea de comandos, pero esto significa que hay un rastro de esa contraseña en mi archivo .bash_history, así como en los procesos en ejecución. Entonces, en su lugar, me gustaría que se le solicite una contraseña al usuario, si es posible de forma silenciosa.¿Cómo puedo hacer que un script espere una contraseña?

¿Sabe si es posible o no solicitar al usuario una contraseña con la expectativa?

Gracias.

Editar: si me estuviera conectando a servidores en lugar de enrutadores, probablemente usaría claves ssh en lugar de contraseñas. Pero los enrutadores que uso solo admiten contraseñas.

Respuesta

28

Uso esperar es stty comando como este:

# grab the password 
stty -echo 
send_user -- "Password for [email protected]$host: " 
expect_user -re "(.*)\n" 
send_user "\n" 
stty echo 
set pass $expect_out(1,string) 

#... later 
send -- "$pass\r" 

Tenga en cuenta que es importante llamar stty -echoantes de llamarsend_user - No estoy seguro exactamente por qué: Creo que es un problema de tiempo.

esperar que todos los programadores deben leer el libro: Exploración de esperar por Don Libes

+2

fresca gracias! Es sorprendente lo intolerante que es este lenguaje: escribí "set pass $ expect_out (1, string)", con un espacio antes de la palabra "string", y se bombardea. No puedo encontrar mucha documentación tampoco. Ojalá hubiera alguna otra solución de la que esperaba. De todos modos, muchas gracias. – MiniQuark

+0

"no se puede encontrar mucha documentación"?!? Hay un libro completo, que generalmente se considera tan bien escrito que no ha necesitado una segunda edición. En serio, revisa ese libro. –

+1

Re: un espacio entre "1" y "cadena" - Tcl (y por lo tanto, espera) no tiene matrices multidimensionales. La clave de matriz es solo una cadena, y "1, cadena" y "1, cadena" son diferentes. –

6

bien, la fusión de las 2 respuestas anteriores (o por debajo o donde quiera que estén ahora!):

#!/usr/local/bin/expect 
log_user 0 
set timeout 10 
set userid "XXXXX" 
set password "XXXXXX" 

# ############## Get two arguments - (1) Device (2) Command to be executed 
set device [lindex $argv 0] 
set command [lindex $argv 1] 

# grab the password 
stty -echo 
send_user -- "Password for [email protected]$host: " 
expect_user -re "(.*)\n" 
send_user "\n" 
stty echo 
set pass $expect_out(1,string) 

spawn /usr/local/bin/ssh -l $userid $device 
match_max [expr 32 * 1024] 

expect { 
    -re "RSA key fingerprint" {send "yes\r"} 
    timeout {puts "Host is known"} 
} 

expect { 
    -re "username: " {send "$userid\r"} 
    -re "(P|p)assword: " {send "$pass\r"} 
    -re "Warning:" {send "$pass\r"} 
    -re "Connection refused" {puts "Host error -> $expect_out(buffer)";exit} 
    -re "Connection closed" {puts "Host error -> $expect_out(buffer)";exit} 
    -re "no address.*" {puts "Host error -> $expect_out(buffer)";exit} 

    timeout {puts "Timeout error. Is device down or unreachable?? ssh_expect";exit} 
} 

expect { 
    -re "\[#>]$" {send "term len 0\r"} 
    timeout {puts "Error reading prompt -> $expect_out(buffer)";exit} 
} 


expect { 
    -re "\[#>]$" {send "$command\r"} 

    timeout {puts "Error reading prompt -> $expect_out(buffer)";exit} 
} 

expect -re "\[#>]$" 
set output $expect_out(buffer) 
send "exit\r" 
puts "$output\r\n" 

Tenga en cuenta que Cambié la variable $ password a $ pass para que sea coherente con la otra respuesta.

0

De forma alternativa, podría dejar que ssh recoja la contraseña a través de X11 utilizando la variable de entorno SSH_ASKPASS.

Desde la página del manual:

> SSH_ASKPASS 
>  If ssh needs a passphrase, it will read the passphrase from the 
>  current terminal if it was run from a terminal. If ssh does not 
>  have a terminal associated with it but DISPLAY and SSH_ASKPASS 
>  are set, it will execute the program specified by SSH_ASKPASS 
>  and open an X11 window to read the passphrase. This is particularly 
>  useful when calling ssh from a .xsession or related script. 
>  (Note that on some machines it may be necessary to redirect the 
>  input from /dev/null to make this work.) 
Cuestiones relacionadas