2009-03-25 6 views
17

Ich habe ein Expect-Skript, das über ssh eine Verbindung zu einigen Routern herstellt. Alle diese Router haben das gleiche Passwort (ich weiß, es ist falsch), und das Skript muss dieses Passwort kennen, um sich mit den Routern verbinden zu können. Derzeit wird das Kennwort als Argument in der Befehlszeile an mein Skript übergeben. Dies bedeutet jedoch, dass in meiner .bash_history-Datei sowie in den ausgeführten Prozessen eine Ablaufverfolgung für dieses Kennwort vorhanden ist. Stattdessen möchte ich, dass der Benutzer nach einem Passwort gefragt wird, wenn möglich stillschweigend.Wie kann ich ein Expect-Skript zur Eingabe eines Passworts veranlassen?

Wissen Sie, ob es möglich ist, den Benutzer zur Eingabe eines Passworts mit zu erwarten?

Vielen Dank.

Bearbeiten: wenn ich eine Verbindung zu Servern anstelle von Routern würde, würde ich wahrscheinlich SSH-Schlüssel anstelle von Passwörtern verwenden. Aber die Router, die ich verwende, unterstützen nur Kennwörter.

Antwort

28

Verwenden erwarten ist stty Befehl wie folgt aus:

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

Beachten Sie, dass es wichtig ist, stty -echo zu nennen vorsend_user Aufruf - Ich bin nicht sicher genau, warum: Ich denke, es ist ein Timing-Problem.

erwarten Programmierer alle lesen sollte das Buch: Explo Erwarten von Don Libes

+2

Cooler Dank! Es ist erstaunlich, wie intolerant diese Sprache ist: Ich schrieb "set pass $ expect_out (1, string)", mit einem Leerzeichen vor dem Wort "string", und es bombardiert. Ich kann auch nicht viel Dokumentation finden. Ich wünschte, es gäbe eine andere Lösung als erwartet. Wie auch immer, vielen Dank. – MiniQuark

+0

"kann nicht viel Dokumentation finden"?!? Es gibt ein ganzes Buch, das allgemein als so gut geschrieben gilt, dass es keine zweite Auflage benötigt. Ernsthaft, überprüfe das Buch. –

+1

Re: ein Leerzeichen zwischen "1" und "string" - Tcl (und daher erwarten) hat keine mehrdimensionalen Arrays. Der Array-Schlüssel ist nur eine Zeichenfolge und "1, Zeichenfolge" und "1, Zeichenfolge" sind unterschiedlich. –

6

OK, die Zusammenführung der zwei Antworten oben (oder unten oder wo auch immer sie sind jetzt!):

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

Beachten Sie, dass Ich habe die Variable $ password in $ pass geändert, um mit der anderen Antwort konsistent zu sein.

0

Alternativ können Sie ssh das Passwort über X11 mit der Umgebungsvariablen SSH_ASKPASS erfassen lassen.

Aus der Manpage:

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