Shell – Send EOF to named pipe – cleaning up / drying up fifo

fifopipeshell-scripttail

If I have some random processes reading from a named pipe:

tail -f MYNAMEDPIPED 
cat MYNAMEDPIPE | someOtherProc

Elsewhere, I have a handle on MYNAMEDPIPED by name.
is there a safe and clean way to stop the tail process by deleting MYNAMEDPIPED or perhaps somehow "drying it up"?

In other words

MYNAMEDPIPED.noMoreDataIsComingThroughSoPleaseStopTailingThis()

🙂

From one of the comments, it says to send EOF to MYNAMEDPIPE. But I cannot figure out how to do this.

This shows the difficulty I am facing:

http://comp.os.linux.questions.narkive.com/2AW9g5yn/sending-an-eof-to-a-named-pipe

Best Answer

EOF is not a character nor an "event" and could not be sent through the pipe, or "fed" to its writing end, as some stubborn urban legend suggests.

The only way to generate an EOF on the reading end of a pipe/fifo (ie cause a read(2) on it to return 0) is to close all open handles to its writing end.

This will happen automatically if all the processes that had opened a named pipe in write mode and all the children that have inherited the file descriptors through fork() are terminated [1].

It's not possible for a read(2) on a named pipe to return 0 it that pipe was opened in read/write mode, eg. with

exec 7<>/path/to/fifo

because in that case there is a single file descriptor / handle for both ends of the pipe and closing the write end will also close the read end making impossible for a read(2) to return 0 (pipes do not support any kind of half-close as sockets do with shutdown(2)).

[1] And all processes that have received the file descriptor via SCM_RIGHTS ancillary message on a unix socket.


Notice that tail -f by definition won't terminate upon EOF, whether the file it's reading from is regular or special. One way to kill all processes that are holding a open handle to a file descriptor is with fuser(1):

tail -f /path/to/fifo
...
> /path/to/fifo  # let any blocking open(2) through
fuser -TERM -k /path/to/fifo

Beware that this will also kill processes that have (inadvertently) inherited an open handle to /path/to/fifo from their parents.

Related Question