2009-03-25 7 views
17

Ho uno script previsto che si connette a pochi router tramite ssh. Tutti questi router hanno la stessa password (lo so, è sbagliato) e lo script deve conoscere quella password per potersi connettere ai router. Attualmente, la password viene passata al mio script come argomento sulla riga di comando, ma ciò significa che c'è una traccia di quella password nel mio file .bash_history e nei processi in esecuzione. Quindi preferirei che all'utente venga richiesta una password, se possibile silenziosamente.Come posso creare un prompt di script previsto per una password?

Sapete se è possibile richiedere all'utente una password con aspettativa?

Grazie.

Modifica: se mi collegassi ai server anziché ai router, probabilmente userei le chiavi ssh invece delle password. Ma i router che sto usando supportano solo le password.

risposta

28

Usa si aspettano è stty comando come questo:

# 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" 

Nota che è importante chiamare stty -echoprima chiamare send_user - non sono sicuro esattamente perché: Penso che sia un problema di temporizzazione.

si aspettano i programmatori dovrebbero leggere il libro: Exploring Aspettatevi da Don Libes

+2

fresco grazie! È incredibile quanto sia intollerante questa lingua: ho scritto "set pass $ expect_out (1, stringa)", con uno spazio prima della parola "stringa", e bombarda. Non riesco nemmeno a trovare molta documentazione. Vorrei che ci fosse qualche altra soluzione del previsto. Comunque, grazie molte. – MiniQuark

+0

"Impossibile trovare molta documentazione"?!? C'è un intero libro, che è generalmente considerato così ben scritto che non ha avuto bisogno di una seconda edizione. Seriamente, controlla quel libro. –

+1

Ri: uno spazio tra "1" e "stringa" - Tcl (e quindi aspettarsi) non ha matrici multidimensionali. La chiave dell'array è solo una stringa e "1, stringa" e "1, stringa" sono diversi. –

6

OK, la fusione delle 2 risposte di cui sopra (o al di sotto o ovunque si trovino ora!):

#!/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" 

Si noti che Ho modificato la variabile $ password in $ pass per essere coerente con l'altra risposta.

0

In alternativa, è possibile consentire a ssh di raccogliere la password tramite X11 utilizzando la variabile di ambiente SSH_ASKPASS.

Dalla pagina man:

> 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.)