expect command is not working in bash script

aditya  picture aditya · Jun 15, 2012 · Viewed 15.2k times · Source

I have a problem related to expect.

when i run abc.sh which includes following lines

#!/usr/bin/expect
spawn scp /etc/httpd/conf/httpd.conf 192.168.0.12:/tmp
######################
expect {
-re "password:" {
exp_send "PASSWORD\r"
}
}
interact

its works fine

but when i use similar code in my running script it doesnt work


#!/bin/bash
clear
while read -u3 LINE
do
code .........
code .......
code  ........

REMOTE_COMMANDS1="scp -r -v $BASE_DIRECTORY/$USERNAME $D_IPADDRESS:/home/"

spawn $REMOTE_COMMANDS1
######################
expect {
-re "password:" {
exp_send "redhat\r"
}
}
interact


done 3< /opt/sitelist.txt

it gives error

./script.sh: line 62: syntax error near unexpected token }' ./script.sh: line 62:}'

i think it is due to the fact that i am not including #!/usr/bin/expect in top of the script but if i use this and execute my script it doesnt do any thing and display all of code in terminal after excution. so can we include #!/usr/bin/expect and #!/bin/bash simultaneously ?

Regards, Aditya

Answer

glenn jackman picture glenn jackman · Jun 15, 2012

Of course bash cannot interpret expect commands, just as bash cannot interpret Java/Perl/Python syntax. There are a couple of approaches.

Write the expect script as a separate program and invoke it from the bash script:

#!/bin/bash
clear
while read -u3 LINE
do
    #...
    ./expect_scp.exp "$BASE_DIR" "$D_IPADDRESS" "$USERNAME" "$PASSWORD"
done 3< /opt/sitelist.txt

and expect_scp.exp is

#!/usr/bin/expect

set base_dir  [lindex $argv 0]
set remote_ip [lindex $argv 1]
set username  [lindex $argv 2]
set password  [lindex $argv 3]
# or
foreach {base_dir remote_ip username password} $argv {break}

spawn scp -rv $base_dir/$username $remote_ip:/home/
expect -re "password:"
exp_send -- "$password\r"
interact

You can put the expect script inside the bash script with proper attention to quoting. Fortunately single quotes are not special to expect.

#!/bin/bash
clear
export BASE_DIR D_IPADDRESS USERNAME PASSWORD
while read -u3 LINE
do
    #...
    expect -c '
        spawn scp -rv $env(BASE_DIR)/$env(USERNAME) $env(D_IPADDRESS):/home/
        expect -re "password:"
        exp_send -- "$env(PASSWORD)\r"
        interact
    '
done 3< /opt/sitelist.txt