taalf
taalf

Reputation: 179

Break a repetitive "expect/send" flow when meeting a sentence

The following bash script is a game. It asks several times the same question give the next thing.

The first thing is apple, the second is cheese, the third is bread and the fourth is bacon.

After a random amount of questions, it asks to say hello.

Examples:

give the next thing
apple
give the next thing
cheese
and now say hello
hello
bravo !

or:

give the next thing
apple
and now say hello
cheese
you failed!

The aim is to win this game using expect within a bash script and with an infinite timeout.

The game.sh script:

#!/bin/bash
min=1;max=4;imax=0
while [ "$imax" -lt "$min" ]; do imax=$RANDOM; let "imax %= $((max+1))"; done
i=1
for thing in apple cheese bread bacon; do
  echo "give the next thing"; read ans
  if [ ! "$ans" == "$thing" ]; then echo "you failed!"; exit 1; fi
  let "i += 1"
  if [ "$i" -gt "$imax" ]; then break; fi
done
echo "and now say hello"; read ans
if [ ! "$ans" == "hello" ]; then echo "you failed!"; exit 1; fi
echo "bravo !"
exit 0

The expect script basis, which wins the game only when the number of questions is exactly 4:

#!/bin/bash

expect << DONE

  spawn sh game.sh

  set timeout -1

  expect "give the next number"
  send "apple\n"

  expect "give the next number"
  send "cheese\n"

  expect "give the next number"
  send "bread\n"

  expect "give the next number"
  send "bacon\n"

  expect "and now say hello"
  send "hello\n"

DONE

exit 0

I have tried many things and I don't see how to check the "and now say hello" sentence between each "give the next thing" sentence. The following structure cannot help since the first questions are all similar and the answers has to be different each time:

expect {
  "give the next thing" {do something; exp_continue}
  "and now say hello" {send "hello\n"}
}

Upvotes: 0

Views: 169

Answers (1)

glenn jackman
glenn jackman

Reputation: 247072

The bones of the answer will be along the lines of:

proc do_something {n} {
    # do something given the counter value $n
    return [lindex {apple cheese bread bacon} $n]
}

set count 0
expect {
    "give the next thing" {
        send "[do_something $count]\r"
        incr count
        exp_continue
    }
    "and now say hello" {send "hello\r"}
}

Upvotes: 1

Related Questions