use expect to enter password when need sudo in script - ubuntu-14.04

I am using Ubuntu 14.04 and installed expect. I am trying to write a script to enter password when it prompted.
UPDATED Code:
#!/usr/bin/expect -d
set timeout 20
set pw odroid
spawn sudo apt-get update
expect {\[sudo]\ password for odroid: }
send "$pw\r"
close
Any suggestions? thx
UPDATE Errors:
expect: does "" (spawn_id exp4) match glob pattern "\[sudo]\ password for odroid: "? no
[sudo] password for odroid:
expect: does "[sudo] password for odroid: " (spawn_id exp4) match glob pattern "\[sudo]\ password for odroid: "? yes
expect: set expect_out(0,string) "[sudo] password for odroid: "
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "[sudo] password for odroid: "
send: sending "odroid\r" to { exp4 }

A more generic way of solving your issue would be matching on assword
expect "*?assword*"
This allows for a more generic script where the username is irrelevant.
I also had the following issue with the snippet below. Basically $pw gets interpreted by the shell and needs to be set outside the expect TCL code.
pw="Password1234"
expect -f - <<-EOF
set timeout 10
spawn sudo -k
spawn sudo mysql_secure_installation
expect "*?assword*"
send -- "$pw\r"
expect eof
EOF

You have too many quotes. Choose one of:
expect {\[sudo\] password for odroid: }
expect "\\\[sudo\\\] password for odroid: "
Clearly the first option is better.
Lots of escaping is necessary because 1) square brackets are special in a glob pattern, and 2) square brackets are special Tcl syntax (command substitution) in double quotes but not in curly braces.

Try to replace with this, it should work fine.
expect "\[sudo\] password for odroid:\r"

Related

Error while running expect in unix

Getting error while running expect script in bash script
Input:
{
/usr/bin/expect << EOF
spawn ssh execsped#10.150.10.194 "cd /home/execsped/ram_test_72;./testecho.sh \"$evenno\" \"$eisinno\" \"$efilename\""
expect "Password"
send "abc#123\r"
expect "*#*"
EOF
}
Output:
extra characters after close-quote
while executing
"spawn ssh execsped#10.150.10.72 "cd /home/execsped/evoting_test_72;./testecho.sh "10575" "_eVoting.pdf" "abc.pdf"
"
remove the escaped quotes. look at the final command it's trying to run: "cd /home/execsped/evoting_test_72;./testecho.sh "10575" "_eVoting.pdf" "abc.pdf" " it should run fine without the escaped quotes.

Expect script - quotes needed with send string conflict with quotes required by expect

I'm trying to use expect to remotely login into a server a change a user password. The application requires that if the password you want to change contains special characters that it be quoted. Problem is, the expect send statement needs to be quoted as well, and when I try and combine the two, the script fails. If I remove the quotes from around the password and use no special characters it runs fine.
send "CHANGEUSERPASSWORD $username PASSWORD "etdgsfdh$"\r"
If I use the line above and run the script I get
extra characters after close-quote
while executing
"send "CHANGEUSERPASSWORD $username PASSWORD "e"
Also, it seems to dislike only the $ character as I can append a # to the end of the password without enclosing it in quotes and the script runs fine. How can I get this to work using a password that contains a $ which requires me to wrap it in quotes, which then apparently conflicts with expect quoting? Please note that the $ can be anywhere in the password, not just at the end as in my example.
Here is my full script for context:
#!/usr/bin/expect -f
set password [lindex $argv 0];
spawn telnet 192.168.100.100 106
expect "200 PWD Server ready"
send "USER user\r"
expect "300 please send the PASS"
send "PASS pass\r"
expect "200 login OK, proceed"
send "CHANGEUSERPASSWORD $username PASSWORD "etdgsfdh$"\r"
expect "200 OK"
send "quit\r"
interact
I have also tried to set the password as a variable using this line:
set password [lindex $argv 0];
And changing this line:
send "CHANGEACCOUNTPASSWORD user PASSWORD $password;" send "\r"
Then I run
./script password
and I get this error:
usage: send [args] string
while executing
"send "CHANGEUSERPASSWORD user PASSWORD $password;" send "\r""
What am I doing wrong?
You can simply escape the inner quotes
send "CHANGEUSERPASSWORD $username PASSWORD \"etdgsfdh$\"\r"
Note that a $ is only special when it's followed by a valid variable name (that may be in braces) -- see http://tcl.tk/man/tcl8.6/TclCmd/Tcl.htm#M12
I assume you're quoting the password because the remote system needs it to be quoted. To answer your question, you'd do:
lassign $argv username passwd # grab the command line arguments
...
send "CHANGEUSERPASSWORD $username PASSWORD \"$passwd\"\r"
If the remote system doesn't require the literal quotes, then simply
send "CHANGEUSERPASSWORD $username PASSWORD $passwd\r"
It is quite simple:
Create a password variable:
set password {etdgsfdh$}
Then send the password to the system:
send "CHANGEUSERPASSWORD $username PASSWORD ${password}\r"
This worked for me.
The only way to escape double quotes in Expect (in my example: "someurl.org" and "_blank") that worked for me was this:
send {UPDATE tablename SET value = ' visible link name ' WHERE id = 1;}
Escaping those four double quotes with a backslash in front of each of them did not work for me.

Expect script to handle RSA finger print keys

I am trying to make my expect script more robust and to be able to handle more situations to be more automated. Currently my script works fine, however, there are times where I will be asked to add the RSA keys to known_hosts, I want this to default to yes all the time. My server doesn't always ask for the keys, once added then after awhile it wont ask until you delete the keys or switch gatways. After looking online i have tried to add this (commented code) in my working code and after added that it stalls at password input screen if RSA key had been added already.
So my question is, is there a way to handle this situation lets say if RSA has been added already, it will just skip to the password line?
[user#gateway my_direcotry]$ cat loadItTest
#!/usr/bin/expect -f
set timeout 600
set user root
set host 1.1.1.1
set pass pass
spawn ssh $user#$host
#expect {
# -re "RSA key fingerprint" {send "yes\r"}
#}
expect "assword:"
send "$pass\r"
expect "#"
Sample output:
[root#gateway my_direcotry]# loadItTest
spawn ssh root#1.1.1.1
root#1.1.1.1's password:
This is where the exp_continue command comes into play, to essentially create a "loop" within the expect command:
spawn ssh $user#$host
expect {
"RSA key fingerprint" {send "yes\r"; exp_continue}
"assword:" {send "$pass\r"}
}
expect "#"
If you see the "RSA key" pattern, answer "yes" but then keep waiting for the "assword" pattern. If you don't see "assword" before "RSA key", that's OK.
The body for the "assword" pattern does not contain exp_continue. After you send the password, the enclosing expect command will return, and the next command is to expect your prompt.
Note I removed the -re option: there are no regex-special characters in that pattern.

Passing Variable with Special characters as password breaks bash script. How do I Sanitize special characters in bash?

I am looking for a solution to sanitizing variables in my bash password change script.
The script below is working, however I have found that some "Special Characters" will break my script. I am not controlling at the moment what Characters are being passed through. I am either looking to sanitize the variables before passing them through, or pushing the variables as a whole untouched. I have tried using '${PASS}' in place of "${PASS}" however the script would not complete when this was the case.
I would appreciate any recommendations anyone could offer. I have tried searching for the answer to this question before posting but didn't find anything relative so i am sorry if this has been answered elsewhere.
#!/bin/bash
# Two variables are passed, Username and new Password.
USERNAME=$1
PASS=$2
expect << EOF
spawn passwd ${USERNAME}
expect "Enter new UNIX password:"
send "${PASS}\r"
expect "Retype new UNIX password:"
send "${PASS}\r"
expect eof;
EOF
expect << EOF
spawn htdigest /.passwd "Authenticated Users" ${USERNAME}
expect "New password:"
send "${PASS}\r"
expect "Re-type new password:"
send "${PASS}\r"
expect eof;
EOF
expect << EOF
spawn htpasswd /squiddb ${USERNAME}
expect "New password:"
send "${PASS}\r"
expect "Re-type new password:"
send "${PASS}\r"
expect eof;
EOF
Thank you in advance!
Send the username and password to the expect scripts via command-line arguments to expect instead. As done now, a double quote would confuse expect since the here-to document is interpolated fully before sent to expect's stdin.
A password like 'hej"' without the single quotes would lead to a send command for expect looking like this:
send "hej"\r"
expect will not enjoy that.
You can access the argument via argv, beware of quoting. Do not that you will expose the username and password to anyone doing "ps" on that box if you pass them as arguments on the command line to expect. But you already do that when calling the script in the question...
Why not use the Expect shell directly for doing this.
#!/usr/bin/expect
set timeout 20
set user [lindex $argv 0]
set password [lindex $argv 1]
spawn passwd $user
expect "Enter new UNIX password:"
send "$password\r";
expect "Retype new UNIX password:"
send "$password\r";
wait 1
spawn htdigest /.passwd "Authenticated Users" $user
expect "New password:"
send "$password\r"
expect "Re-type new password:"
send "$password\r"
wait 1
spawn htpasswd /squiddb $user
expect "New password:"
send "$password\r"
expect "Re-type new password:"
send "$password\r"
exit 0
Execute the above like
./SCRIPTNAME.exp user password

how to ignore the backslash in expect script

I create the following script (expect under ksh ) ,
in order to copy the file data.txt from Linux machine to windows machine
scp process will be automatic by expect , so password question will be answered by expect
the problem is that expect can’t ignore the "\" backslash from the following line
spawn scp /tmp/data.txt ADMIN#192.9.200.17:'c:\'
so from output I see that expect send the line without the "\" backslash
what need to change in my syntax/script so expect will ignore the backslash ?
my script
#!/bin/ksh
PASSORD=secret123
SCP=`cat << EOF
set timeout -1
spawn scp /var/tmp/data.txt ADMIN#192.9.200.17:'c:\'
expect {
")?" { send "yes\r" ; exp_continue }
word: {send $PASSORD\r}
}
expect eof
EOF`
expect -c "$SCP"
.
results ( output )
spawn scp /var/tmp/data.txt ADMIN#192.9.200.17:'c:'
gcs#198.202.183.97's password:
scp: c:: Error opening file: The requested operation failed.
Killed by signal 1.
Use spawn scp /tmp/data.txt ADMIN#192.9.200.17:'c:/' instead as it should evaluate to the same path.
You need to escape \.
Try
spawn scp /tmp/data.txt ADMIN#192.9.200.17:'c:\\'

Resources