Подтвердить что ты не робот

Как я могу ожидать приглашение script для пароля?

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

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

Спасибо.

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

4b9b3361

Ответ 1

Используйте команду wait 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 - я не уверен, почему именно: я думаю, что это проблема времени.

Ожидайте, что программисты должны прочитать книгу the: Изучение ожиданий дон Либес

Ответ 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, чтобы соответствовать другому ответу.

Ответ 3

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

На странице 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.)