shelltimeoutnamed-pipes

write to fifo/pipe from shell, with timeout


I have a pair of shell programs that talk over a named pipe. The reader creates the pipe when it starts, and removes it when it exits.

Sometimes, the writer will attempt to write to the pipe between the time that the reader stops reading and the time that it removes the pipe.

reader: while condition; do read data <$PIPE; do_stuff; done
writer: echo $data >>$PIPE
reader: rm $PIPE

when this happens, the writer will hang forever trying to open the pipe for writing.

Is there a clean way to give it a timeout, so that it won't stay hung until killed manually? I know I can do

#!/bin/sh
# timed_write <timeout> <file> <args>
# like "echo <args> >> <file>" with a timeout

TIMEOUT=$1
shift;
FILENAME=$1
shift;
PID=$$

(X=0; # don't do "sleep $TIMEOUT", the "kill %1" doesn't kill the sleep
 while [ "$X" -lt "$TIMEOUT" ];
 do sleep 1; X=$(expr $X + 1);
 done; kill $PID) &

echo "$@" >>$FILENAME
kill %1

but this is kind of icky. Is there a shell builtin or command to do this more cleanly (without breaking out the C compiler)?


Solution

  • This pair of programs works much more nicely after being re-written in Perl using Unix domain sockets instead of named pipes. The particular problem in this question went away entirely, since if/when one end dies the connection disappears instead of hanging.