I made 2 processes run in parallel that communicate with a named pipe. I noticed a strange behaviour: every write should be followed by a read or vice versa! If we break the rule the program hangs and if we terminate it with ctrl+C the child still hangs meaning that it just can't re-read any more.
My example:
#!/bin/bash
shopt -u failglob
shopt -s extglob nullglob dotglob
function london (){
local message answer fifo id return exitcode
fifo=fifo_$RANDOM.$RANDOM.$RANDOM.$$
mkfifo ${fifo}
#trap 'rm -rf "$fifo"' EXIT
( berlin $fifo ) &
id=$!
echo "parent id: $$, child id: $id"
message='Greetings from London!(1)'
echo "$message" > $fifo
echo "1. parent sent it's 1st message"
#*****write-to-write error!*****#
message='Greetings from London!(2)'
#read -r answer < $fifo
echo "$message" > $fifo
echo "2. parent sent it's 2nd message"
wait
rm -rf $fifo
}
function berlin (){
local message answer fifo
fifo=$1
read -r answer < $fifo
echo 'Berlin says:> '"$answer"
#*****read-to-read error!*****#
#echo 'next' > $fifo
read -r answer < $fifo
echo 'Berlin says:> '"$answer"
}
london
Under the points where I've inserted the "write-to-write" or "read-to-read" messages there are 2 commented lines that solve the problem making me think that the above rule mysteriously holds!!! Any ideas what is going on?
Here's the output:
parent id: 4921, child id: 4923
1. parent sent it's 1st message
2. parent sent it's 2nd message
Berlin says:> Greetings from London!(1)
Thanks!
I think now everything is clear and is condensed in one phrase: "keep the pipe open from the reader's part".
Suppose now, I want to add a second input file descriptor for "some" of my commands inside the loop; how can I do this? Here is my new Berlin function:
function berlin (){
local message answer fifo
fifo=$1
while true; do
read -r answer
echo 'Berlin says:> '"$answer"
#this fails!
read -r -p "reading from fd0: " <&0
if [[ $answer = 'quit' ]]; then
break
fi
done < "$fifo" 3>"$fifo"
}
As one can see, we use file descriptor 3 for pipe but when we try to read from fd 0 we actually read from fd 3! Is there a way to achieve this?