I have an expect script that I need to login to a remote system and execute commands. This script works with the exception of providing the password to the root account. The root password contains a dollar sign that I cannot seem to get to work. Here is the code
#!/usr/bin/expect
set timeout 3
set username "root"
set password "Pas$word"
set hostname [lindex $argv 0]
log_user 0
send_user "\n#####\n# $hostname\n#####\n"
spawn ssh -q -o StrictHostKeyChecking=no $username@$hostname
expect {
timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
eof { send_user "\nSSH failure for $hostname\n"; exit 1 }
"*assword"
}
send "$password\r"
expect {
timeout { send_user "\nLogin failed. Password incorrect.\n"; exit 1}
"*\$ "
}
send_user "\nPassword is correct\n"
expect "$ " { send "ls" }
I have verified this works when providing credentials whose passwords don't contain the dollar sign, but I can't get it to work with the root account. It always produces the Login failed. Password incorrect
timeout error. Changing the password is not an option. I have tried to supply the \
escape character in the password definition like so:
set password "Pas\$word"
And I get the same results... any ideas on what I'm doing wrong?
Thanks
EDIT As I said. I already tried to escape the $ character. But to clarify, I added a print statement for the password when the script starts up to verify the variable contains the password correctly... Here is the change:
set password "Pas\$word"
...
send_user "\n#####\n# $hostname\n#####\n"
send_user "Using password: $password\n"
...
Here is the console output:
njozwiak@ubuntu:~$ ./ssh_ls.sh 192.168.5.93
#####
# 192.168.5.93
#####
Using password: Pas$word
Login failed. Password incorrect.
I've found a makeshift solution for this. I'm sure this problem solved long ago, just mentioning how I solved mine:
Actual password:
Pas$word
Assign to variable password:
set password {Pas\$word}
In TCL(or expect in your code), grouping words within double braces {} disables substitution within the braces, thus your password will be stored as:
Pas\$word
Now in the end, when you send password via expect Pas\$word
will be translated as Pas$word
which is the actual password.
But the problem is if the password is unknown, for example, password is in an encrypted file or has to be taken as user input. I was looking for this type of cases where I don't know where and how many $ sings are in the password.