5

I want to write to a named pipe only if it already has a reader. Currently, I'm using timeout to detect whether the attempt to write to the pipe blocked, like so:

#! /usr/bin/env bash
rm -f pipe
mkfifo pipe
sleep 5

timeout 1 bash -c "echo Hello > pipe"

if [[ $? == 0 ]]
then
    echo Somebody got our message
else
    echo Nobody read from pipe, so we didn\'t send a message
fi

This works. If I tail -f pipe in a separate terminal during the sleep I get one message, and if I don't, I get the other. But is there a better way? Ideally it would be something that doesn't rely on a timeout.

4

If you want to write to the pipe, only if there are some process that has opened it for reading, you could open it for writing in non-blocking mode.

With GNU dd:

echo Hello | dd oflag=nonblock of=pipe status=none &&
  echo message has been sent

And you'll get the error message for ENXIO (something like No such device or address in English) if there was no reader.

Note that it would also fail (with EWOULDBLOCK/EAGAIN, Resource temporarily unavailable) if the pipe is full (if there is a reader, but it is not currently reading and something like 64KiB have already been written to it).

Also note that not all of the message may be written if it wouldn't fit. If you remove the status=none, you'll see how much was written.

  • on bsd I get dd: unknown operand oflag – Alexander Mills Jun 4 at 19:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.