questions.sh
#!/bin/bash
declare -a animals=("dog" "cat")
declare -a num=("1" "2" "3")
for a in "${animals[@]}"
do
for n in "${num[@]}"
do
echo "$n $a ?"
read REPLY
echo "Your answer is: $REPLY"
done
done
responder.sh
#!/usr/bin/expect -f
set timeout -1
spawn ./questions.sh
while true {
expect {
"*dog*" { send -- "bark\r" }
"^((?!dog).)*$" { send -- "mew\r" }
}
}
expect eof
running: './responder.sh'
expected outcome:
1 dog ?
bark
Your answer is: bark
2 dog ?
bark
Your answer is: bark
3 dog ?
bark
Your answer is: bark
1 cat ?
mew
Your answer is: mew
2 cat ?
mew
Your answer is: mew
3 cat ?
mew
Your answer is: mew
actual outcome: hang at 'cat' question and not responding...
1 dog ?
bark
Your answer is: bark
2 dog ?
bark
Your answer is: bark
3 dog ?
bark
Your answer is: bark
1 cat ?
tried and searched multiple ways but still not working. thank you very much.
The expect program hangs because you match the first "dog", send bark, then you
expect eof
with an infinite timeout. Of course you don't have "eof" because the shell script is waiting for input.You need to use the
exp_continue
command for your loops, notwhile
:I made the patterns much more specific: either "dog" or "not dog" followed by a space, question mark and end-of-line characters.
The
exp_continue
commands will keep the code looping within the expect command until "eof" is encountered.We can make the pattern a little DRYer:
(This is not a direct answer to your question. Just FYI.)
You can write Expect-like scripts with shell code only. For your example:
The
question.sh
:The
responder.sh
:Run it: