2009-03-25 7 views
17

У меня есть сценарий ожидания, который соединяется с несколькими маршрутизаторами через ssh. Все эти маршрутизаторы имеют один и тот же пароль (я знаю, это неправильно), и сценарий должен знать этот пароль, чтобы иметь возможность подключаться к маршрутизаторам. В настоящее время пароль передается моему сценарию в качестве аргумента в командной строке, но это означает, что в моем файле .bash_history и в запущенных процессах есть след этого пароля. Поэтому вместо этого я хотел бы, чтобы пользователь запрашивал пароль, если возможно, молча.Как я могу вызвать приглашение сценария ожидания для пароля?

Знаете ли вы, можно ли запросить у пользователя пароль с ожиданием?

спасибо.

Редактировать: Если бы я подключался к серверам вместо маршрутизаторов, я бы, скорее всего, использовал ключи ssh вместо паролей. Но маршрутизаторы, которые я использую, просто поддерживают пароли.

ответ

28

Использование ожидать это stty команда так:

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

Обратите внимание, что это важно, чтобы позвонить stty -echoперед тем вызова send_user - Я не знаю точно, почему: я думаю, что это вопрос времени.

ожидать программисты все должны прочитать книга: Изучение Ожидать Дон LIBES

+2

Круто спасибо! Удивительно, насколько нетерпим этот язык: я написал «set pass $ expect_out (1, string)», пробел перед словом «string», и он бомбит. Я тоже не могу найти документацию. Хотелось бы, чтобы было другое решение, чем ожидалось. Во всяком случае, большое спасибо. – MiniQuark

+0

«Не могу найти много документации»?!? Есть целая книга, которая, как правило, считается настолько хорошо написанной, что ей не требуется второе издание. Серьезно, проверьте эту книгу. –

+1

Re: пробел между «1» и «строкой» - Tcl (и, следовательно, ожидание) не имеет многомерных массивов. Ключ массива - это просто строка, а «1, строка» и «1, строка» - разные. –

6

ОК, слияние 2 ответов выше (или ниже, или там, где они сейчас):

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

Обратите внимание, что Я изменил переменную $ password на $ pass, чтобы соответствовать другому ответу.

0

В качестве альтернативы вы можете передать ssh пароль через X11 с использованием переменной среды SSH_ASKPASS.

От человека странице:

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