Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

expect, interact and then again expect

There are several posts regarding the same, but i still not able to make my expect script work properly. My intention is to automate everything but leave the password enter for the user. So there are 3 parts of the script:

  1. automated login
  2. give the user interaction to enter the password
  3. give control back to Expect script to continue work

So i have script which will be spawned and which have 3 read commands. First and last should be filled by Expect and second one i would like to enter my self:

#!/bin/ksh
read user?User:
echo "Expect entered the username $user"
read pass?Password:
echo "User entered the password $pass"
read command?"Shell>"
echo "Expect entered the command $command"

My expect script:

#!/usr/bin/expect
spawn ./some_script
expect User
send I-am-expect\r
expect Password
interact
expect Shell
send I-am-expect-again

Unfortunately after i have entered the password the script does not continue and left in the interact mode:

[root@localhost ~]# ./my-expect
spawn ./some_script
User:I-am-expect
Expect entered the username I-am-expect
Password:i am user
User entered the password i am user
Shell>

And finally when i entering something on the "Shell" and pressing [ENTER] expect exits with the error:

Expect entered the command
expect: spawn id exp4 not open
    while executing
"expect Shell"
    (file "./my-expect" line 7)
[root@localhost ~]#

I appriciate any explanation or resolution of this issue. I am using expect version 5.45

like image 675
Petras L Avatar asked Nov 22 '15 12:11

Petras L


2 Answers

You can read (expect_user) the user's password by yourself and then send it to the spawn'ed program. For example:

[STEP 101] # cat foo.exp
proc expect_prompt {} \
{
    global spawn_id
    expect -re {bash-[.0-9]+(#|\$)}
}

spawn ssh -t 127.0.0.1 bash --noprofile --norc
expect "password: "

stty -echo
expect_user -timeout 3600 -re "(.*)\[\r\n]"
stty echo
send "$expect_out(1,string)\r"

expect_prompt
send "exit\r"
expect eof
[STEP 102] # expect foo.exp
spawn ssh -t 127.0.0.1 bash --noprofile --norc
[email protected]'s password:
bash-4.3# exit
exit
Connection to 127.0.0.1 closed.
[STEP 103] #
like image 65
pynexj Avatar answered Sep 18 '22 22:09

pynexj


The interact should be given with proper condition for the exit criteria.

The following script will execute the user commands in the shell

exeCmds.sh

#!/bin/bash
read -p "User: " user
echo "Expect entered the username $user"
read -p "Password: " pass
echo "User entered the password $pass"
while :
do
        # Simply executing the user inputs in the shell
        read -p "Shell> " command
        $command
done

automateCmdsExec.exp

#!/usr/bin/expect 
spawn ./exeCmds.sh
expect User
send dinesh\r
expect Password
send welcome!2E\r
expect Shell>
puts "\nUser can interact now..."
puts -nonewline "Type 'proceed' for the script to take over\nShell> "
while 1 {
        interact "proceed" {puts "User interaction completed.";break}
}
puts "Script take over the control now.."

# Now, sending 'whoami' command from script to shell
send "whoami\r"
expect Shell>

# Your further code here...

The script automateCmdsExec.exp will address the login needs of the bash script and when the prompt arrives, it will hand over the control to user.

We should define an exit criteria for the interact for which I have used the word proceed. (You can alter it as per your need).

Once interact matched the word proceed. it will return the control back to the expect script.

For demo purpose, I kept one more send-expect pair of command.

i.e.

send "whoami\r"
expect Shell>

You can keep your further code below the interact, thus it can be executed by script.

like image 41
Dinesh Avatar answered Sep 18 '22 22:09

Dinesh