showkey
showkey

Reputation: 270

How to jump the infinite while loop when all data read out of the pipe?

cat  pipe.sh
#!/bin/bash
fifo_file=fifo.pipe
mkfifo $fifo_file
exec 6<>$fifo_file
rm $fifo_file

DateWrite ()
{
    i=0
    while [ $i -lt 100 ]
    do
        str=`date`
        i=$(( i+1 ))
        echo "$i $str"
    done
}

for  (( i=0; i<10; i++ ))
do 
     ( DateWrite >&6 ) &
done
while read date_time
do
    echo $date_time >> output.file
done <&6

The above bash code create a named pipe,DateWrite function write a string in pipe,it create a 10 process with for loop ,read data from pipe with while loop.
bash pipe.sh can't stop,it enter into a infinite while loop.
How to jump the while loop when all data read out of the pipe?
Another issue:Why rm $fifo_file after exec 6<>$fifo_file?

Try as @chepner say:

vim pipe.sh
#!/bin/bash
fifo_file=fifo.pipe
mkfifo $fifo_file
exec 6<>$fifo_file
rm $fifo_file

DateWrite ()
{
    i=0
    while [ $i -lt 100 ]
    do
        str=`date`
        i=$(( i+1 ))
        echo "$i $str"
    done
}

writers=()
for  (( i=0; i<10; i++ ))
do 
     ( DateWrite >&6 ) & writers+=($!)
done

while read date_time
do
    echo $date_time >> output.file
done <&6 &

for writer in "${writers[@]}"; do
  wait "$writer"
done

exec 6>&-

It works fine. There are two lines here i don't understand.

writers=()
 ( DateWrite >&6 ) & writers+=($!)

What does it mean?

Upvotes: 1

Views: 320

Answers (1)

chepner
chepner

Reputation: 531345

Your while loop will try to read from the pipe as long as it is open for writing. Once all the writers have completed, you can close the pipe explicitly.

fifo_file=fifo.pipe
mkfifo $fifo_file
exec 6<>$fifo_file
rm $fifo_file

writers=()
for  (( i=0; i<10; i++ ))
do 
     ( DateWrite >&6 ) & writers+=($!)
done

while read date_time
do
    echo $date_time >> output.file
done <&6 &

for writer in "${writers[@]}"; do
  wait "$writer"
done

exec 6>&-

Upvotes: 3

Related Questions