Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to send a password with a $ symbol in Expect Script

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.
like image 797
linsek Avatar asked Jul 29 '13 16:07

linsek


People also ask

How to pass special character as password in shell script?

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.

How do you send Ctrl C in Expect script?

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.


2 Answers

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
like image 141
John Mayor Avatar answered Sep 18 '22 08:09

John Mayor


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.

like image 28
Hasan Rumman Avatar answered Sep 22 '22 08:09

Hasan Rumman