I am trying to write a shell script that starts a program, reads from its stdout and can write to its stdin.
I'm having trouble to get it to work, I tried using named pipes, and using exec and file descriptors.
Just couldn't get it to work, so I thought I'll post it here to see if someone is willing to help me.
The program is called primes, and it first asks for my name
>What's your name?
<test
>Hi, test
>Given 10 numbers, calculate sum of its prime factors!
>1 : 187
>Sum:
<answer1
>2 : 123
<answer2
...
Sure, I can show, but I had many versions and just in general have no clue how to do this.
I'm currently trying to create a named pipe for the input, so that I can write to that in my script (> $pipe).
Then I'm running the primes program in the background, which gets the $pipe on stdin.
I did a tail -f there to keep it opened, otherwise the stream would close when I write to it with for instance echo "test name" > $pipe.
But, it doesn't work, and I'm also not even sure how to debug this.
#!/bin/bash
mkfifo /tmp/primes.input
tail -f /tmp/primes.input | /tmp/primes >&0 &
echo "test name" > /tmp/primes.input
while true
do
if read line; then
echo "read: $line"
if [[ "$line" == *"1 : "* ]]; then
echo "Solve this one: $line"
echo "12345" > /tmp/primes.input
fi
fi
done
------ Post updated at 03:00 PM ------
Now using this version. I thought I should perhaps not background the program. But this also doesn't seem to work.
This version does not output anything when I start it ... (not seeing the "read: ..." and also not seeing any output of the program).
#!/bin/bash
PROGRAM=/tmp/primes
mkfifo $PROGRAM.stdin
tail -f $PROGRAM.stdin | $PROGRAM | while true
do
if read line; then
echo "read: $line"
if [[ "$line" == *"What's your name?"* ]]; then
echo "test name" > $PROGRAM.stdin
elif [[ "$line" == *"1 : "* ]]; then
echo "Solve this one: $line"
echo "12345" > $PROGRAM.stdin
fi
fi
done
The first question i have is: how exactly is the program reading the input?
If this is done via the gets() the problem might be a missing EOL ("\n") or EOF character at the end of the input line. Some programs (i.e. passwd also clear their <stdin> to make sure that redirection does not take place. Your program might have a similar mechanism in place.
Other than that: you might want to explore the "coprocess-facility" of the Korn shell if you want to bidirectionally communicate with asynchronously running jobs. If i remember correctly some versions of bash have that too now, but i have no experience with this in bash . It seems to work slightly different there than in Korn shell.