如何让 Expect 脚本提示输入密码?
题
我有一个通过 ssh 连接到几个路由器的期望脚本。所有这些路由器都有相同的密码(我知道,这是错误的),并且脚本需要知道该密码才能连接到路由器。目前,密码作为命令行上的参数传递给我的脚本,但这意味着我的 .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 的《探索 Expect》
其他提示
行,合并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收集的密码。
从人页:
> 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.)
不隶属于 StackOverflow