Bash: using fifo

I wrote two bash scripts with consumer-producer paradigm on a fifo (named pipe).

This is a simple example:

## producer.sh
...
fifo="/path/to/fifo"

consumer.sh &
while [ ! -p "${fifo}" ]; do
sleep 1
done

while [...]; do
echo "message for logging"
echo "message for fifo" >"${fifo}"
done

...

## consumer.sh
...
fifo="/path/to/fifo"

trap "rm -f ${fifo}" INT EXIT TERM

[ -p "${fifo}" ] || mkfifo "${fifo}"

while read line <"${fifo}"; do
echo ${line}
done

...

These scripts have two problems: (1) for each echo (write) in the producer, bash open the fifo, write on it and close it (but this is not a real problem…); (2)  for each read in the consumer (in the while loop), bash has the same behaviour (open, read, close). This causes a failure on the write in the producer (errno==EPIPE) when the fifo is closed for reading.

Solution: use the standard template open -> read/write (in the while loop) -> close

## producer.sh
...
fifo="/path/to/fifo"

consumer.sh &
while [ ! -p "${fifo}" ]; do
sleep 1
done

exec 10>"${fifo}"

while [...]; do
echo "message for logging"
echo "message for fifo" >&10
done

exec 10>&-
...

## consumer.sh
...
fifo="/path/to/fifo"
trap "rm -f ${fifo}" INT EXIT TERM

[ -p "${fifo}" ] || mkfifo "${fifo}"

exec 10<"${fifo}"

while read line <&10; do
echo ${line}
done

exec 10<&-
...

One thought on “Bash: using fifo

  1. Why not reduce exec overhead with?

    while read line <&10: do

    done 10<"$fifo"

Lascia un commento