期待スクリプトでパスワードの入力を求めるようにするにはどうすればよいですか?
質問
SSH 経由でいくつかのルーターに接続する Expect スクリプトがあります。これらのルーターはすべて同じパスワードを持っており (間違っていることはわかっていますが)、スクリプトはルーターに接続できるようにそのパスワードを知る必要があります。現在、パスワードはコマンド ラインの引数としてスクリプトに渡されますが、これは、実行中のプロセスだけでなく .bash_history ファイルにもそのパスワードの痕跡が存在することを意味します。したがって、代わりに、可能であればサイレントでユーザーにパスワードの入力を求めるプロンプトを表示したいと考えています。
Expect を使用してユーザーにパスワードの入力を求めることができるかどうか知っていますか?
ありがとう。
編集:ルーターではなくサーバーに接続している場合は、おそらくパスワードの代わりに ssh キーを使用するでしょう。しかし、私が使用しているルーターはパスワードのみをサポートしています。
解決
期待値を使用する stty
次のようなコマンド:
# grab the password
stty -echo
send_user -- "Password for $user@$host: "
expect_user -re "(.*)\n"
send_user "\n"
stty echo
set pass $expect_out(1,string)
#... later
send -- "$pass\r"
電話することが重要であることに注意してください stty -echo
前に 電話をかける send_user
-- 正確な理由はわかりません。タイミングの問題だと思います。
プログラマは全員読むべきだと期待してください の 本:Don Libes による「期待の探索」
他のヒント
OK、上記の2件の回答合併(以下またはどこ彼らは今を!):
#!/usr/bin/expect
log_user 0
set timeout 10
set userid "XXXXX"
set pass "XXXXXX"
### Get two arguments - (1) Host (2) Command to be executed
set host [lindex $argv 0]
set command [lindex $argv 1]
# grab the password
stty -echo
send_user -- "Password for $userid@$host: "
expect_user -re "(.*)\n"
send_user "\n"
stty echo
set pass $expect_out(1,string)
spawn /usr/bin/ssh -l $userid $host
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 host 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"
私は$に$パスワード変数を変更する注は、他の答えと一致するように渡します。
別の方法としては、sshがSSH_ASKPASS環境変数を使用してX11を経由してパスワードを収集してみましょうことができます。
の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.)