Expect script to change default password - expect

I'm trying to build a simple Expect script to change the default password. Our admin forces us to change passwords immediately after deploying a new system in our cloud infrastructure. I want to build an Expect script because I have to do this across a few dozen systems.
The prompts look like this:
❯ ssh root#mysystem.company.com
root#mysystem.company.com's password:
You are required to change your password immediately (administrator enforced)
Last login: Tue Aug 23 12:14:58 2022 from 10.123.45.67
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user root.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
Connection to mysystem.company.com closed.
My expect script looks like this:
#! /usr/local/bin/expect -f
set timeout 60
set user [lindex $argv 0]
set host [lindex $argv 1]
set old [lindex $argv 2]
set new [lindex $argv 3]
spawn -noecho ssh -q -o StrictHostKeychecking=no "$user\#$host"
expect "password:"
send "$old\r"
expect "New password"
send "$new\r"
expect "Retype new password:"
send "$new\r"
That 1st expect statement is working, but I cannot figure out why the 2nd expect statement isn't working:
❯ expect spawn root mysystem.company.com oldPassword newPassword
root#mysystem.company.com's password:
You are required to change your password immediately (administrator enforced)
Last login: Tue Aug 23 13:14:12 2022 from 10.123.45.67
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user root.
New password: %
It immediately exits from the script once it reaches New password:. I've tried various things but not figuring this out.
Please help!
It was suggested to re-run with -d (debug) enabled. The output appears to show its working as expected (no pun intended), but the password wasn't actually changed. When I attempt to login, I'm prompted through the same steps. Maybe someone else can help interpret this output:
❯ expect -d spawn root mysystem.company.com lgmPjgY2xTJH 73a40HpVCgRey9fP
expect version 5.45
argv[0] = expect argv[1] = -d argv[2] = spawn argv[3] = root argv[4] = mysystem.company.com argv[5] = lgmPjgY2xTJH argv[6] = 73a40HpVCgRey9fP
set argc 4
set argv0 "spawn"
set argv "root mysystem.company.com lgmPjgY2xTJH 73a40HpVCgRey9fP"
executing commands from command file spawn
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {10930}
expect: does "" (spawn_id exp6) match glob pattern "password:"? no
expect: does "\r" (spawn_id exp6) match glob pattern "password:"? no
root#mysystem.company.com's password:
expect: does "\rroot#mysystem.company.com's password: " (spawn_id exp6) match glob pattern "password:"? yes
expect: set expect_out(0,string) "password:"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "\rroot#mysystem.company.com's password:"
send: sending "lgmPjgY2xTJH\r" to { exp6 }
expect: does " " (spawn_id exp6) match glob pattern "New password"? no
expect: does " \r\n" (spawn_id exp6) match glob pattern "New password"? no
You are required to change your password immediately (administrator enforced)
Last login: Wed Aug 24 20:01:38 2022 from 10.123.45.678
WARNING: Your password has expired.
You must change your password now and login again!
expect: does " \r\nYou are required to change your password immediately (administrator enforced)\r\nLast login: Wed Aug 24 20:01:38 2022 from 10.123.45.678\r\r\nWARNING: Your password has expired.\r\nYou must change your password now and login again!\r\n" (spawn_id exp6) match glob pattern "New password"? no
Changing password for user root.
expect: does " \r\nYou are required to change your password immediately (administrator enforced)\r\nLast login: Wed Aug 24 20:01:38 2022 from 10.123.45.678\r\r\nWARNING: Your password has expired.\r\nYou must change your password now and login again!\r\nChanging password for user root.\r\n" (spawn_id exp6) match glob pattern "New password"? no
New password:
expect: does " \r\nYou are required to change your password immediately (administrator enforced)\r\nLast login: Wed Aug 24 20:01:38 2022 from 10.123.45.678\r\r\nWARNING: Your password has expired.\r\nYou must change your password now and login again!\r\nChanging password for user root.\r\nNew password: " (spawn_id exp6) match glob pattern "New password"? yes
expect: set expect_out(0,string) "New password"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) " \r\nYou are required to change your password immediately (administrator enforced)\r\nLast login: Wed Aug 24 20:01:38 2022 from 10.123.45.678\r\r\nWARNING: Your password has expired.\r\nYou must change your password now and login again!\r\nChanging password for user root.\r\nNew password"
send: sending "73a40HpVCgRey9fP\r" to { exp6 }
expect: does ": " (spawn_id exp6) match glob pattern "Retype new password:"? no
expect: does ": \r\n" (spawn_id exp6) match glob pattern "Retype new password:"? no
Retype new password:
expect: does ": \r\nRetype new password: " (spawn_id exp6) match glob pattern "Retype new password:"? yes
expect: set expect_out(0,string) "Retype new password:"
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) ": \r\nRetype new password:"
send: sending "73a40HpVCgRey9fP\r" to { exp6 }
❯ echo $?
0

According to the expect -d output, the script stopped after sending the password for the Retype new password: prompt.
So just add expect eof at the end of the script.
This is the most common mistake when using Expect. You must wait for the spawned program to finish.
(credit goes to #sexpect)

Related

Extract EXPECT result to local variable/file

I've been struggling with getting the output from a remote server to a local variable or a local file.
My attempt:
#!/bin/bash
my_pass=!!psw!!
server=10.10.10.10
/usr/bin/expect << ENDOFEXPECT
exp_internal 1 ;# expect internal debugging. remove when not needed
set PROMPT ":~ ?# ?"
set timeout 30
spawn bash -c "ssh root#$server"
expect "assword:"
send "$my_pass\r"
expect -re "$PROMPT"
send -- "df -kh /\r"
expect -re "df\[^\n]+\n.+\n(.+\r\n.+)\r\n"
set command_output $expect_out(1,string)
send_user "$command_output\r"
interact
ENDOFEXPECT
echo "====================="
echo " >> $command_output"
Output:
spawn bash -c ssh root#10.10.10.10
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {154725}
expect: does "" (spawn_id exp4) match glob pattern "assword:"? no
Password:
expect: does "\rPassword: " (spawn_id exp4) match glob pattern "assword:"? yes
expect: set expect_out(0,string) "assword:"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "\rPassword:"
send: sending "!!psw!!\r" to { exp4 }
Gate keeper glob pattern for '' is ''. Not usable, disabling the performance booster.
expect: does " " (spawn_id exp4) match regular expression ""? (No Gate, RE only) gate=yes re=yes
expect: set expect_out(0,string) ""
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) ""
send: sending "df -kh /\r" to { exp4 }
Gate keeper glob pattern for 'df[^
]+
.+
(.+
.+)
' is ''. Not usable, disabling the performance booster.
expect: does " " (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
expect: does " \r\n" (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
Last login: Fri Dec 2 23:58:09 2022 from 10.10.10.1
Welcome to server image 2.2
expect: does " \r\nLast login: Fri Dec 2 23:58:09 2022 from 10.10.10.1\r\r\n\r\nWelcome to server image 2.2\r\n\r\n" (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
REMY_SERVER:~ #
expect: does " \r\nLast login: Fri Dec 2 23:58:09 2022 from 10.10.10.1\r\r\n\r\nWelcome to server image 2.2\r\n\r\n\u001b[?1034h\u001b[1m\u001b[31mREMY_SERVER:~ # \u001b(B\u001b[m" (spawn_id exp4) match regular expression "df[^\n]+\n.+\n(.+\r\n.+)\r\n"? (No Gate, RE only) gate=yes re=no
expect: timed out
interact: received eof from spawn_id exp0
=====================
>>
Expected:
What I ultimately want is to get the output of df -kh into a local variable or even better, append it directly to a local file (on the local machine, not the server on which the command is executed) so that it contains something like:
$ cat ./result.txt
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 20G 18G 1,7G 92% /
Method 1: The proper way is to not use expect and use key pair access :
Step #1
Setup a SSH key pair (google it) and then copy the SSH key to the remote server. To do this I'd recommend using ssh-copy-id.
Step #2
Now with the ability to SSH to a server in place using a key, your above problem turns into this:
$ ssh root#10.10.10.10 "df -kh"
You can get fancy and use here documents (heredocs aka. here-docs) to further enhance this technique.
$ ssh root#10.10.10.10 <<EOF
> df -kh
> EOF
or put the commands in a file and pass them to ssh:
$ ssh root#10.10.10.10 < my.cmds
Method 2: Expect
See the following, expains how to use it properly and a tool to create expect scripts
https://hostadvice.com/how-to/how-to-automate-tasks-in-ssh/
First, your PROMPT regex is not matching. I see the output has some colour codes in it:
expect: does " \r\nLast login: ...REMY_SERVER:~ # \u001b(B\u001b[m" (spawn_id exp4) match regular expression ...
It's good to anchor prompt regexes, and to enclose them in braces. Try
set PROMPT { # \S*$}
Or, assuming the login shell is bash, set a new prompt that's easier to match:
send "$my_pass\r"
expect "Welcome to server"
send -- "PS1='>'\r"
set PROMPT {>$}
expect -re $PROMPT
Next, the relevant code for the question.
send -- "df -kh /\r"
expect -re "df\[^\n]+\n.+\n(.+\r\n.+)\r\n"
set command_output $expect_out(1,string)
send_user "$command_output\r"
I'd adjust your regex a touch:
set cmd "df -kh /"
send -- "$cmd\r"
expect -re "$cmd\r\n(.+)\r\n.*$PROMPT"
Then you're capturing and "echoing" the result correctly
set command_output $expect_out(1,string)
send_user "$command_output\n"
# use a newline here ......^
And to append it to a local file:
set fh [open ./results.txt a]
puts $fh $command_output
close $fh

bash telnet get stdout from expect

I need to get a dataset from a telnet shell, for this I have looked at expect https://www2.lib.uchicago.edu/keith/tcl-course/topics/expect.html
This is my expect script:
/usr/bin/expect -d << EOD
spawn telnet myhost
log_user 1
set timeout 10
expect "Login:"
send "user\n\r"
expect "Password:"
send "password\n\r"
expect "*$*"
send "AT\n\r"
expect "OK"
send "AT&CSR\n"
expect "OK"
send "AT!G=A6\n"
expect "OK"
send "AT^MI=0\n"
expect "OK"
send "AT^SX=0\n"
expect "OK"
send "AT^SR=0,1"
expect "*$*"
send "exit\r"
Now I can connect to the remote host, send command, but cannot read the results, here a shell result:
> expect: does " " (spawn_id exp4) match glob pattern "*"? yes expect:
> set expect_out(0,string) " " expect: set expect_out(spawn_id) "exp4"
> expect: set expect_out(buffer) " " send: sending "AT\n\r" to { exp4 }
>
> expect: does "" (spawn_id exp4) match glob pattern "OK"? no
> ********
>
> OK
>
> expect: does "********\r\n\r\nOK\r\n" (spawn_id exp4) match glob
> pattern "OK"? yes expect: set expect_out(0,string) "OK" expect: set
> expect_out(spawn_id) "exp4" expect: set expect_out(buffer)
> "********\r\n\r\nOK" send: sending "AT&CSR\n" to { exp4 }
>
> expect: does "\r\n" (spawn_id exp4) match glob pattern "OK"? no AT
>
> expect: does "\r\nAT\r\n" (spawn_id exp4) match glob pattern "OK"? no
>
> OK
>
> expect: does "\r\nAT\r\n\r\nOK\r\n" (spawn_id exp4) match glob pattern
> "OK"? yes expect: set expect_out(0,string) "OK" expect: set
> expect_out(spawn_id) "exp4" expect: set expect_out(buffer)
> "\r\nAT\r\n\r\nOK" send: sending "AT!G=A6\n" to { exp4 }
>
> expect: does "\r\n" (spawn_id exp4) match glob pattern "OK"? no AT&CSR
> expect: does "\r\nAT&CSR" (spawn_id exp4) match glob pattern "OK"? no
> AT!G=A6 expect: does "\r\nAT&CSRAT!G=A6" (spawn_id exp4) match glob
> pattern "OK"? no expect: timed out send: sending "AT^MI=0\n" to { exp4
> }
>
> expect: does "\r\nAT&CSRAT!G=A6" (spawn_id exp4) match glob pattern
> "OK"? no AT^MI=0
If the result of the command doesn't match the expected it goes to next command, is there a way to catch the response result?
EDIT:
I tried to simplify thing and added interact, without no luck:
/usr/bin/expect -d << EOD
> spawn telnet myhost
> log_user 1
> interact"
> EOD
expect version 5.45.4
argv[0] = /usr/bin/expect argv[1] = -d
set argc 0
set argv0 "/usr/bin/expect"
set argv ""
executing commands from command file
spawn telnet myhost
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {11306}
invalid command name "interact""
while executing
"interact""
The way you send your AT commands is wrong.
According to ETSI specification 127.007, by default AT commands are terminated by \r (IRA 13 - ASCII carriage return) character[1]. For further details, see paragraph "4.1 - Command line".
In order to fix your issue, just send AT\r instead of AT\n\r, AT&CSR\r instead of AT&CSR\n and so on (the latter is a mistake you repeated for every following AT command). Otherwise the AT parser won't recognize your commands correctly.
[1] Command line termination character can be customized by means of ATS3 command, with the following syntax:
ATS3=<value>
Where <value> is the decimal ASCII value of the new command line termination character (default is 13).

Bash and expect: can't reboot router via telnet

I'm trying to reboot a D-Link router by connecting to it via telnet through expect.
The problem is that I can't execute (through the expect script) any of the commands supported by the router.
First of all, I show you a short telnet session with my router:
telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
BCM96338 ADSL Router
Login: admin
Password:
> swversion show
EU_3-12-01-1R00.A2pB026.d20m
> logout
Bye bye. Have a nice day!!!
Connection closed by foreign host.
Now I'm trying to make it automatic with an Expect script but I can't make it work. Here's the script:
#!/usr/bin/expect -f
#exp_internal 1
set timeout 30
#router username
set name admin
#command to execute
set routercmd "swversion show"
#router password
set pass mypassword
#router IP address
set routerip 192.168.1.1
spawn telnet $routerip
# send username & password
expect "Login: "
send "$name\r"
expect "Password: "
send "$pass\r"
expect "> "
send "$routercmd\r"
expect "> "
When I execute the script, it gets stuck at the password prompt:
./reboot_dut.sh
spawn telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.
BCM96338 ADSL Router
Login: admin
Password:
If I uncomment the #exp_internal 1 line I get:
./reboot_dut.sh
spawn telnet 192.168.1.1
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {6398}
expect: does "" (spawn_id exp7) match glob pattern "Login: "? no
Trying 192.168.1.1...
expect: does "Trying 192.168.1.1..." (spawn_id exp7) match glob pattern "Login: "? no
expect: does "Trying 192.168.1.1...\r\n" (spawn_id exp7) match glob pattern "Login: "? no
Connected to 192.168.1.1.
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1." (spawn_id exp7) match glob pattern "Login: "? no
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\n" (spawn_id exp7) match glob pattern "Login: "? no
Escape character is '^]'.
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\nEscape character is '^]'." (spawn_id exp7) match glob pattern "Login: "? no
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\nEscape character is '^]'.\r\n" (spawn_id exp7) match glob pattern "Login: "? no
BCM96338 ADSL Router
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\nEscape character is '^]'.\r\nBCM96338 ADSL Router\r\n" (spawn_id exp7) match glob pattern "Login: "? no
Login:
expect: does "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\nEscape character is '^]'.\r\nBCM96338 ADSL Router\r\nLogin: " (spawn_id exp7) match glob pattern "Login: "? yes
expect: set expect_out(0,string) "Login: "
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "Trying 192.168.1.1...\r\nConnected to 192.168.1.1.\r\nEscape character is '^]'.\r\nBCM96338 ADSL Router\r\nLogin: "
send: sending "admin\r" to { exp7 }
expect: does "" (spawn_id exp7) match glob pattern "Password: "? no
a
expect: does "a" (spawn_id exp7) match glob pattern "Password: "? no
dmin
Password:
expect: does "admin\r\nPassword: " (spawn_id exp7) match glob pattern "Password: "? yes
expect: set expect_out(0,string) "Password: "
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "admin\r\nPassword: "
send: sending "mypassword\r" to { exp7 }
expect: does "" (spawn_id exp7) match glob pattern "> "? no
expect: timed out
send: sending "swversion show\r" to { exp7 }
expect: does "" (spawn_id exp7) match glob pattern "> "? no
> swversion show
expect: does "\r\n> swversion show\r\n" (spawn_id exp7) match glob pattern "> "? yes
expect: set expect_out(0,string) "> "
expect: set expect_out(spawn_id) "exp7"
expect: set expect_out(buffer) "\r\n> "
SOLUTION: I found the solution to the problem. The router I was trying to reboot was a D-LINK 2640B. A working expect script for this router is:
#!/usr/bin/expect -f
spawn telnet ROUTER_IP
match_max 10000
expect *login:*
sleep 2
send -- "USERNAME\r"
expect *assword:*
sleep 2
send -- "PASSWORD\r"
expect *>*
send -- "\r"
expect *>*
send -- "COMMAND\r"
expect *>*
send -- "\r"
expect *>*
send -- "logout\r"
I'd say you need to match your prompt to ">", as opposed to "> " (i.e. no space after it).

grep ipaddress from file in expect script

this is the code, and I'm stuck in the line where I need to grep IP address from file $filename,
#!/usr/local/bin/expect --
###Made by Etihkru####
set env(TERM) vt100
set env(SHELL) /bin/sh
set env(HOME) /usr/local/bin
set PASSWORD er
set SIU [lindex $argv 0]
exp_internal 1
spawn ssh mashost
set USER admin
set PASS hidden
expect {
"assword" {send "$PASSWORD\r"}
}
expect "ranosusr#rn2osscs603"
send -- "cd /var/opt/bla/edd/ARNE_SIU \r"
expect "ranosusr#rn2osscs603"
send -- "grep -il $SIU *\r"
set prompt {ranosusr#rn2osscs603> }
expect -re "($SIU\\S+\\.xml).*$prompt$"
set filename $expect_out(1,string)
send -- "/opt/ericsson/arne/bin/import.sh -f -val:rall\r"
expect "ranosusr#rn2osscs603"
send -- "/opt/ericsson/arne/bin/import.sh -f -import\r"
expect "ranosusr#rn2osscs603"
send -- "cat $filename | grep {1,3\}\.\{1,3\}\.\{1,3\}\.\{1,3\} \r"
expect -re "{1,3\}\.\{1,3\}\.\{1,3\}\.\{1,3\}" *$prompt$"
set IP $expect_out(1,string)
sleep 10s
spawn ssh admin#$IP
expect {
-re "RSA key fingerprint" {send "yes\r"}
timeout {puts "Host is known"}
}
expect {
"assword" {send "$PASS\r"}
}
expect "Osmon>"
send -- "resumePMMeasurements STN=0,MeasurementDefinition=0 sftp://pmup-rn2sossv605:er#10.211.149.60/GRAN/rn2sossv605/$SIU/NeTransientUp \r"
expect "Osmon>"
send -- "getalarmlist \r"
expect -re "(\Operation Succeed\)"
send -- "rev \r"
expect "Osmon>"
send -- "subscribe 10.211.149.40 1 \r"
expect "Osmon>"
send -- "getsubscriptionstatus 1 \r"
expect "Osmon>"
interact
the output is :
perl siu1 FRTAMX
spawn ssh mashost
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {1162}
expect: does "" (spawn_id exp4) match glob pattern "assword"? no
expect: does "\r\n|-----------------------------------------------------------------|\r\n| This system is for the use of authorized users only. |\r\n| Individuals using this computer system without authority, or in |\r\n| excess of their authority, are subject to having all of their |\r\n| activities on this system monitored and recorded by system |\r\n| personnel. |\r\n| |\r\n| In the course of monitoring individuals improperly using this |\r\n| system, or in the course of system maintenance, the activities |\r\n| of authorized users may also be monitored. |\r\n| |\r\n| Anyone using this system expressly consents to such monitoring |\r\n| and is advised that if such monitoring reveals possible |\r\n| evidence of criminal activity, system personnel may provide the |\r\n| evidence of such monitoring to law enforcement officials. |\r\n|-----------------------------------------------------------------|\r\n\r\n" (spawn_id exp4) match glob pattern "assword"? no
Password:
expect: does "\r\n|-----------------------------------------------------------------|\r\n| This system is for the use of authorized users only. |\r\n| Individuals using this computer system without authority, or in |\r\n| excess of their authority, are subject to having all of their |\r\n| activities on this system monitored and recorded by system |\r\n| personnel. |\r\n| |\r\n| In the course of monitoring individuals improperly using this |\r\n| system, or in the course of system maintenance, the activities |\r\n| of authorized users may also be monitored. |\r\n| |\r\n| Anyone using this system expressly consents to such monitoring |\r\n| and is advised that if such monitoring reveals possible |\r\n| evidence of criminal activity, system personnel may provide the |\r\n| evidence of such monitoring to law enforcement officials. |\r\n|-----------------------------------------------------------------|\r\n\r\nPassword: " (spawn_id exp4) match glob pattern "assword"? yes
expect: set expect_out(0,string) "assword"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "\r\n|-----------------------------------------------------------------|\r\n| This system is for the use of authorized users only. |\r\n| Individuals using this computer system without authority, or in |\r\n| excess of their authority, are subject to having all of their |\r\n| activities on this system monitored and recorded by system |\r\n| personnel. |\r\n| |\r\n| In the course of monitoring individuals improperly using this |\r\n| system, or in the course of system maintenance, the activities |\r\n| of authorized users may also be monitored. |\r\n| |\r\n| Anyone using this system expressly consents to such monitoring |\r\n| and is advised that if such monitoring reveals possible |\r\n| evidence of criminal activity, system personnel may provide the |\r\n| evidence of such monitoring to law enforcement officials. |\r\n|-----------------------------------------------------------------|\r\n\r\nPassword"
send: sending "bla\r" to { exp4 }
expect: does ": " (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
expect: does ": \r\n" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
Last login: Wed Mar 12 15:42:34 2014 from rn2sosas601
expect: does ": \r\nLast login: Wed Mar 12 15:42:34 2014 from rn2sosas601\r\r\n" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
You have new mail.
expect: does ": \r\nLast login: Wed Mar 12 15:42:34 2014 from rn2sosas601\r\r\nYou have new mail.\r\n" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
ranosusr#rn2osscs603>
expect: does ": \r\nLast login: Wed Mar 12 15:42:34 2014 from rn2sosas601\r\r\nYou have new mail.\r\nranosusr#rn2osscs603> " (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? yes
expect: set expect_out(0,string) "ranosusr#rn2osscs603"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) ": \r\nLast login: Wed Mar 12 15:42:34 2014 from rn2sosas601\r\r\nYou have new mail.\r\nranosusr#rn2osscs603"
send: sending "cd /var/opt/bla/edd/ARNE_SIU \r" to { exp4 }
expect: does "> " (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
cd /var/opt/e
expect: does "> cd /var/opt/e" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
ricsson/edd
expect: does "> cd /var/opt/bla/edd" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
/ARNE_SIU
expect: does "> cd /var/opt/bla/edd/ARNE_SIU \r\r\n" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
ranosusr#rn2osscs603>
expect: does "> cd /var/opt/bla/edd/ARNE_SIU \r\r\nranosusr#rn2osscs603> " (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? yes
expect: set expect_out(0,string) "ranosusr#rn2osscs603"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "> cd /var/opt/bla/edd/ARNE_SIU \r\r\nranosusr#rn2osscs603"
send: sending "grep -il FRTAMX *\r" to { exp4 }
expect: does "> " (spawn_id exp4) match regular expression "(FRTAMX\S+\.xml).*ranosusr#rn2osscs603> $"? no
grep -il FRTAMX *
expect: does "> grep -il FRTAMX *\r\r\n" (spawn_id exp4) match regular expression "(FRTAMX\S+\.xml).*ranosusr#rn2osscs603> $"? no
FXL704_FRTAMX_SIU_ARNE.xml
FXL704_FRTAMX_SIU_ARNE_upgraded_temp.xml
expect: does "> grep -il FRTAMX *\r\r\nFXL704_FRTAMX_SIU_ARNE.xml\r\nFXL704_FRTAMX_SIU_ARNE_upgraded_temp.xml\r\n" (spawn_id exp4) match regular expression "(FRTAMX\S+\.xml).*ranosusr#rn2osscs603> $"? no
ranosusr#rn2osscs603>
expect: does "> grep -il FRTAMX *\r\r\nFXL704_FRTAMX_SIU_ARNE.xml\r\nFXL704_FRTAMX_SIU_ARNE_upgraded_temp.xml\r\nranosusr#rn2osscs603> " (spawn_id exp4) match regular expression "(FRTAMX\S+\.xml).*ranosusr#rn2osscs603> $"? yes
expect: set expect_out(0,string) "FRTAMX_SIU_ARNE.xml\r\nFXL704_FRTAMX_SIU_ARNE_upgraded_temp.xml\r\nranosusr#rn2osscs603> "
expect: set expect_out(1,string) "FRTAMX_SIU_ARNE.xml"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "> grep -il FRTAMX *\r\r\nFXL704_FRTAMX_SIU_ARNE.xml\r\nFXL704_FRTAMX_SIU_ARNE_upgraded_temp.xml\r\nranosusr#rn2osscs603> "
send: sending "/opt/bla/arne/bin/import.sh -f -val:rall\r" to { exp4 }
expect: does "" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
/opt/bla/arne/bin/import.sh
expect: does "/opt/bla/arne/bin/import.sh" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
-f -val:rall
expect: does "/opt/bla/arne/bin/import.sh -f -val:rall\r\r\n" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
Logging to file /var/opt/bla/arne/ARNE_Import_Log.2014-03-12_15:43:36
expect: does "/opt/bla/arne/bin/import.sh -f -val:rall\r\r\nLogging to file /var/opt/bla/arne/ARNE_Import_Log.2014-03-12_15:43:36\r\n" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
Failed to write to file. Writing to stdout instead.
The file '-val:rall' can not be found.
expect: does "/opt/bla/arne/bin/import.sh -f -val:rall\r\r\nLogging to file /var/opt/bla/arne/ARNE_Import_Log.2014-03-12_15:43:36\r\nFailed to write to file. Writing to stdout instead.\r\nThe file '-val:rall' can not be found.\r\n" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
ranosusr#rn2osscs603>
expect: does "/opt/bla/arne/bin/import.sh -f -val:rall\r\r\nLogging to file /var/opt/bla/arne/ARNE_Import_Log.2014-03-12_15:43:36\r\nFailed to write to file. Writing to stdout instead.\r\nThe file '-val:rall' can not be found.\r\nranosusr#rn2osscs603> " (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? yes
expect: set expect_out(0,string) "ranosusr#rn2osscs603"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "/opt/bla/arne/bin/import.sh -f -val:rall\r\r\nLogging to file /var/opt/bla/arne/ARNE_Import_Log.2014-03-12_15:43:36\r\nFailed to write to file. Writing to stdout instead.\r\nThe file '-val:rall' can not be found.\r\nranosusr#rn2osscs603"
send: sending "/opt/bla/arne/bin/import.sh -f -import\r" to { exp4 }
expect: does "> " (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
/opt/ericsso
expect: does "> /opt/ericsso" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
n/arn
expect: does "> /opt/bla/arn" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
e/bin/import.sh -f
expect: does "> /opt/bla/arne/bin/import.sh -f" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
-import
expect: does "> /opt/bla/arne/bin/import.sh -f -import" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
expect: does "> /opt/bla/arne/bin/import.sh -f -import\r\r\n" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
Logging to file /var/opt/bla/arne/ARNE_Import_Log.2014-03-12_15:43:40
expect: does "> /opt/bla/arne/bin/import.sh -f -import\r\r\nLogging to file /var/opt/bla/arne/ARNE_Import_Log.2014-03-12_15:43:40\r\n" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
Failed to write to file. Writing to stdout instead.
The file '-import' can not be found.
expect: does "> /opt/bla/arne/bin/import.sh -f -import\r\r\nLogging to file /var/opt/bla/arne/ARNE_Import_Log.2014-03-12_15:43:40\r\nFailed to write to file. Writing to stdout instead.\r\nThe file '-import' can not be found.\r\n" (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? no
ranosusr#rn2osscs603>
expect: does "> /opt/bla/arne/bin/import.sh -f -import\r\r\nLogging to file /var/opt/bla/arne/ARNE_Import_Log.2014-03-12_15:43:40\r\nFailed to write to file. Writing to stdout instead.\r\nThe file '-import' can not be found.\r\nranosusr#rn2osscs603> " (spawn_id exp4) match glob pattern "ranosusr#rn2osscs603"? yes
expect: set expect_out(0,string) "ranosusr#rn2osscs603"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "> /opt/bla/arne/bin/import.sh -f -import\r\r\nLogging to file /var/opt/bla/arne/ARNE_Import_Log.2014-03-12_15:43:40\r\nFailed to write to file. Writing to stdout instead.\r\nThe file '-import' can not be found.\r\nranosusr#rn2osscs603"
send: sending "cat FRTAMX_SIU_ARNE.xml | grep {1,3}.{1,3}.{1,3}.{1,3} \r" to { exp4 }
couldn't compile regular expression pattern: quantifier operand invalid
while executing
"expect -re "{1,3\}\.\{1,3\}\.\{1,3\}\.\{1,3\}" *$prompt$""
(file "siu1" line 32)
ranosusr#rn2sosas601>
sory for the big ouput, but this is what I got with exp_internal 1. So the problem is with grepin Ip address, some commands I have disabled in code, to be faster until I manage the ipaddress. Thanks

Using expect to confirm a password

What I'm trying to do is write an expect script that backs up all databases on a server, then create an encrypted zip file (I couldn't get my tar/openssl command to run properly in expect) containing the sql file.
This is just an exercise to learn about expect, not a real backup solution.
I'm obviously lacking some understanding here. What I want to do is:
Back up all databases to a file (done)
Run the zip command to create an encrypted zip file (done... sorta)
Respond to "Enter password: "
Then response to the confirmation "Verify password: "
#!/usr/bin/expect -f
exp_internal 1
set backupdir "/mnt/db-backups/"
set now [clock seconds]
set date [clock format $now -format {%Y-%m-%d}]
set filename $date
append filename "_dbbackups.sql"
exec mysqldump -u root --all-databases --events > $backupdir$filename
spawn zip -e $backupdir$filename.enc.zip $backupdir$filename
expect {
"Enter password: " { send "monkey"
exp_continue
}
"Verify password: " {send "monkey"
exp_continue
}
}
And the output is
$expect encrypt.sh
spawn zip -e /mnt/db-backups/2013-12-11_dbbackups.sql.enc.zip /mnt/db-backups/2013-12-11_dbbackups.sql
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {15733}
expect: does "" (spawn_id exp6) match glob pattern "Enter password: "? no
"Verify password: "? no
Enter password:
expect: does "Enter password: " (spawn_id exp6) match glob pattern "Enter password: "? yes
expect: set expect_out(0,string) "Enter password: "
expect: set expect_out(spawn_id) "exp6"
expect: set expect_out(buffer) "Enter password: "
send: sending "monkey" to { exp6 }
expect: continuing expect
expect: does "" (spawn_id exp6) match glob pattern "Enter password: "? no
"Verify password: "? no
monkey
expect: does "monkey" (spawn_id exp6) match glob pattern "Enter password: "? no
"Verify password: "? no
-- then I exited --
It's a pretty simple script... but I'm sucking at it.
The problem is simple:
You have to press return. So just change the command
send "monkey"
to
send "monkey\r"
(both of them)
DRY:
spawn zip -e $backupdir$filename.enc.zip $backupdir$filename
expect {
"* password: " {
send "monkey\r"
exp_continue
}
eof
}
[...] write an expect script [...]
Not how I'd do it.
zip -P password [...]
Knowing nothing about your Zip version ("zip -v"), it's hard to say
if you simply didn't look at the documentation ("zip -h2", "man zip").
Putting a password into a script is a sufficient security hazard that
"-P" was left undocumented until Zip 3.0 (when the developers got tired
of answering the how-do-I questions). But putting a password into a
script once can hardly be worse than putting a password into a script
twice.
Expect is a really ugly and troublesome solution for this.
For the mysqldump part, add your database connection information and the password in ~/.my.cnf following this format:
[client]
database=dbname
user=dbuser
password=dbpass
host=dbhost
If you work with multiple databases, then you'll have to create one file per database, for example ~/.my.cnf.dbname, and call mysqldump like this:
mysqldump --defaults-file=~/.my.cnf.$dbname $dbname | gzip >"$target"
Make sure to do chmod 600 on this file to make it as secure as possible.
And when you encrypt with openssl, you can put the password on the command line like this:
... | openssl des3 -pass pass:monkey >"$target"
You can put this after gzip in the earlier command. Of course, use a different cipher instead of des3 if you want more security. Also, instead of passing the password on the command line, you might want to use file:pathname option instead to get the password from the first line of the file instead.

Resources