Reputation: 121
I have been trying to make a bash script that interacts with a program.
I need to run "script1" (the program, ie. "./script1.sh"), and i need "script2" (bash script) to be run and read the questions, and respond with answers, back to "script1".
It's the actual interaction between the two script i cannot solve.
Restrictions:
expect
or other similar functions is not allowed, it must be run on linux shell commands.I have tried using an array of techniques:
/proc/[pid]/fd/0
(for using stdin, but it seems constricted to terminal and not the shell process itself)./script1.sh | the_pipe
, but this doesn't allow any input to be given back to "script1")./script1.sh < answer.txt > question.txt
, but it seems that answer.txt
is only read once on script start-up?)./script1.sh < answer.pipe > question.pipe
, but the script stalls on start because of the answer.pipe blocks it. If i force a carriage return to the answer.pipe to get the process started, "script1" fails, as the carriage return is a wrong answer)./script_to_parse_questions.sh &
, then saving the result to a file, which is read once and then deleted etc.)I think "the linux way" might probably be to use pipes "|" or brackets "<>", but it's probably just me who cannot get it working properly.
(Edited for clarification)
Upvotes: 0
Views: 357
Reputation: 246807
This is where you would want to use a bash Coprocess (introduced in bash v4.0 -- NEWS)
Suppose we have a file that contains the questions and answers:
$ cat q_and_a
Q1
answer one
this is question two
ans 2
question the third
I say thrice
Then "script1" can read this file, ask the questions in random order, and know what the correct answer is:
$ cat script1.sh
#!/usr/bin/env bash
# read the q_and_a file
qs=()
as=()
while read -r q; read -r a; do
qs+=( "$q" )
as+=( "$a" )
done < q_and_a
# ask the questions in random order
readarray -t order < <(
printf "%d\n" "${!qs[@]}" | shuf
)
for i in "${order[@]}"; do
echo "${qs[i]}"
read -r ans
if [[ $ans == "${as[i]}" ]]; then
echo "answer to '${qs[i]}' is CORRECT"
else
echo "answer to '${qs[i]}' is WRONG"
fi
done
Now, "script2" can invoke script1 as a coprocess, listen for a question, provide the answer, and then listen for the response to the answer:
$ cat script2.sh
#!/usr/bin/env bash
# read the q_and_a file
declare -A qa
while read -r q; read -r a; do
qa[$q]=$a
done < q_and_a
coproc ./script1.sh
for ((i=0; i < ${#qa[@]}; i++)); do
read -r question <& ${COPROC[0]}
echo "script1 asked: '$question'"
echo "answering: '${qa[$question]}'"
echo "${qa[$question]}" >& ${COPROC[1]}
read -r response <& ${COPROC[0]}
echo "script1 responded: '$response'"
done
Running script2 might look like:
$ ./script2.sh
script1 asked: 'this is question two'
answering: 'ans 2'
script1 responded: 'answer to 'this is question two' is CORRECT'
script1 asked: 'question the third'
answering: 'I say thrice'
script1 responded: 'answer to 'question the third' is CORRECT'
script1 asked: 'Q1'
answering: 'answer one'
script1 responded: 'answer to 'Q1' is CORRECT'
Probably in your case, you may not have a shared file with the questions and answers, but you since script2 has the question, you can do what you need to do to analyze it and provide the appropriate answer.
Upvotes: 3