Search code examples
bashshellexpect

Automate 2 scripts interacting with each others using expect


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?


Solution

  • 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] $