Automate 2 scripts interacting with each others using expect

Viewed 92

I have 2 simple scripts that I need them to automatically interact with each others using a third expect script

script1.sh

#!/bin/bash

echo "s1: started"
echo "question1"
read
echo "got ${REPLY}"
echo "question2"
read
echo "got ${REPLY}"
echo "question3"
read
echo "got ${REPLY}"
echo "s1: finished"

script2.sh

#!/bin/bash

echo "s2: started"
read
echo "got ${REPLY}"
echo "answer1"
read
echo "got ${REPLY}"
echo "answer2"
read
echo "got ${REPLY}"
echo "answer3"
echo "s2: finished"

auto_s1_s2.exp

#!/usr/bin/expect

spawn -noecho ./script1.sh
set s1ID $spawn_id

spawn -noecho ./script2.sh
set s2ID $spawn_id

expect -i $s1ID "question1" {
    send_user "exp: question1\n"
    send -i $s2ID "question1\r"
    expect -i $s2ID "answer1" {
        send_user "exp: answer1\n"
        send -i $s1ID "answer1\r"
    }
}
interact

The output of running ./auto_s1_s2.exp however is:

s1: started
question1
exp: question1
question1
s2: started
got question1
answer1
exp: answer1

I am expecting that s1 echoes question1 which is verify against expect $s1ID "question1" then the expect script would send question1 to s2 and expects answer1 from it then it sends answer to s1 and so on

Illustration here

It seems that answer1 was not received by script1

What am I doing wrong here?

3 Answers

Here's a full example.

Shell part:

[STEP 101] $ cat s1.sh
echo "s1: started"
echo "question1"
read
echo "got ${REPLY}"
echo "question2"
read
echo "got ${REPLY}"
echo "question3"
read
echo "got ${REPLY}"
echo "s1: finished"
[STEP 102] $ cat s2.sh
echo "s2: started"
read
echo "got ${REPLY}"
echo "answer1"
read
echo "got ${REPLY}"
echo "answer2"
read
echo "got ${REPLY}"
echo "answer3"
echo "s2: finished"
[STEP 103] $

Expect part:

[STEP 104] $ cat qa.exp
spawn bash s1.sh
set s1 $spawn_id

spawn bash s2.sh
set s2 $spawn_id

expect -i $s1 "s1: started"
expect -i $s2 "s2: started"

expect {
    -i $s1 -re "(question.)" {
        set q $expect_out(1,string)

        send -i $s2 "$q\r"
        expect -i $s2 -re "got\[^\r\n]+\[\r\n]+"
        expect -i $s2 -re "(\[^\r\n]+)\[\r\n]+$"
        set a $expect_out(1,string)

        send -i $s1 "$a\r"

        exp_continue
    }
    -i $s1 eof {
        exp_continue
    }
    -i $s2 eof {
    }
}

Result:

[STEP 105] $ expect qa.exp
spawn bash s1.sh
spawn bash s2.sh
s1: started
question1
s2: started
question1
got question1
answer1
answer1
got answer1
question2
question2
got question2
answer2
answer2
got answer2
question3
question3
got question3
answer3
s2: finished
s2: finished
got s2: finished
s1: finished
[STEP 106] $

Give you an example with sexpect:

[bash] # cat qa.sh
sock1=/tmp/s1.$$.sock
sock2=/tmp/s2.$$.sock

sexpect -s $sock1 spawn bash s1.sh
sexpect -s $sock1 expect 's1: started'

sexpect -s $sock2 spawn bash s2.sh
sexpect -s $sock2 expect 's2: started'

while true; do
    sexpect -s $sock1 expect -re '(question.)'
    ret=$?
    if sexpect chkerr -err $ret -is eof; then
        break
    fi
    q=$( sexpect -s $sock1 expect_out -i 1 )

    sexpect -s $sock2 send -cr "$q"
    sexpect -s $sock2 expect -re $'got[^\r\n]+[\r\n]+'
    sexpect -s $sock2 expect -re $'([^\r\n]+)[\r\n]+$'
    a=$( sexpect -s $sock2 expect_out -i 1 )

    sexpect -s $sock1 send -cr "$a"
done

sexpect -s $sock1 wait
sexpect -s $sock2 wait
[bash] #

Result:

[bash] # bash qa.sh
s1: started
s2: started
question1
question1
got question1
answer1
answer1
got answer1
question2
question2
got question2
answer2
answer2
got answer2
question3
question3
got question3
answer3
s2: finished
s2: finished
got s2: finished
s1: finished
[bash] #

As meuh mentioned in his comment, the expect script is working fine but not showing the output due to the interact not listening to a certain spawn_id

Related