My Expect script shows password/user in clear text and I want to hide it.
#!/usr/local/bin/expect
##################################################################################开发者_运维技巧######### ############
# Input: It will handle two arguments -> a device and a show command.
########################################################################################### ############
# ######### Start of Script ######################
# #### Set up Timeouts - Debugging Variables
log_user 0
set timeout 10
set userid "USER"
set password "PASS"
# ############## Get two arguments - (1) Device (2) Command to be executed
set device [lindex $argv 0]
set command [lindex $argv 1]
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 "$password\r"}
-re "Warning:" {send "$password\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"
... and add -OUseBatchMode=Yes
so that if there is a problem with your keys, ssh will fail immediately (you can verify exit code) rather than just falling back to password mode and hanging (as you are running interactively)
The same issue exists in any scripting language. The script can't type in your password if it doesn't know it... the easiest solution is to use passwordless ssh, using keys.
Have a look at Glenn's answer here: How can I make an expect script prompt for a password?
I was trying to do the same sort of thing and found this useful.
The following is expect code that prompts for the username and password:
send_user "Username?\ "
expect_user -re "(.*)\n"
set user $expect_out(1,string)
send_user "password?\ "
stty -echo
expect_user -re "(.*)\n"
stty echo
set password $expect_out(1,string)
Alternatively if you need multiple runs and don't want to re-enter your password each time then you could store the password in a file in your home directory with restricted permissions (0400) and read in the password from there. Then delete the password file when no longer needed.
When you send password through expect, if you do a 'ps', you can view the entire command with the password. To avoid this, you can call expect script from another bash script sending at about 500 character random string and then the password. Then on expect script you can call password as $1 variable.
Bash script example:
#!/bin/bash
string="6e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d8206e2884f8bf8418bac1ca224472c5d820"
./expectscript $string "MySuperSecretPassword"
And expect script example:
#!/usr/bin/expect -f
set timeout 20
set string [lindex $argv 0]
set password [lindex $argv 1]
spawn ssh "user@192.168.1.1"
expect "assword"
send "$password\r"
Hope this solve your problem.
精彩评论