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.
On UNIX and Linux operating systems, special characters must be escaped using a backslash (\). Note: To escape ! (exclamation mark), use a single quotation mark around the password or use the back slash (\) as the escape character.
All control codes have an equivalent octal sequence in ASCII. "Ctrl-C" has an octal value of three in ASCII, so the Expect sequence would be "\003". To send a "Ctrl-C" in Expect using its octal value, use the command "send \003" in your script.
Try escaping the backslash, that is
Pas$word
becomes
Pas\\\$word
This is a common problem with scripting (even with PHP, Python) where a string gets unescaped twice or even more times!
A full-blown example how I use expect with SFTP, inside a Bash script:
#!/bin/bash
host=mysftp.dmz
port=22
username=john
/usr/bin/expect <<EOF
set timeout -1
spawn sftp -C -oPort=$port $username@$host
expect "password:"
send "Pas\\\$word\r"
expect "sftp>"
send "get data.txt\r"
expect "sftp>"
send "bye\r"
EOF
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With