908 Chapter 44
can be used for reading and writing on the FIFO. Doing this rather subverts the I/O
model for FIFOs, and SUSv3 explicitly notes that opening a FIFO with the O_RDWR
flag is unspecified; therefore, for portability reasons, this technique should be
avoided. In circumstances where we need to prevent blocking when opening a
FIFO, the open() O_NONBLOCK flag provides a standardized method for doing so (refer
to Section 44.9).
Avoiding the use of the O_RDWR flag when opening a FIFO can be desirable for a
another reason. After such an open(), the calling process will never see end-of-
file when reading from the resulting file descriptor, because there will always
be at least one descriptor open for writing to the FIFO—the same descriptor
from which the process is reading.
Using FIFOs and tee(1) to create a dual pipeline
One of the characteristics of shell pipelines is that they are linear; each process in
the pipeline reads data produced by its predecessor and sends data to its successor.
Using FIFOs, it is possible to create a fork in a pipeline, so that a duplicate copy of
the output of a process is sent to another process in addition to its successor in the
pipeline. In order to do this, we need to use the tee command, which writes two
copies of what it reads from its standard input: one to standard output and the
other to the file named in its command-line argument.
Making the file argument to tee a FIFO allows us to have two processes simulta-
neously reading the duplicate output produced by tee. We demonstrate this in the
following shell session, which creates a FIFO named myfifo, starts a background wc
command that opens the FIFO for reading (this will block until the FIFO is opened
for writing), and then executes a pipeline that sends the output of ls to tee, which
both passes the output further down the pipeline to sort and sends it to the myfifo
FIFO. (The –k5n option to sort causes the output of ls to be sorted in increasing
numerical order on the fifth space-delimited field.)
$ mkfifo myfifo
$ wc -l < myfifo &
$ ls -l | tee myfifo | sort -k5n
(Resulting output not shown)
Diagrammatically, the above commands create the situation shown in Figure 44-5.
The tee program is so named because of its shape. We can consider tee as function-
ing similarly to a pipe, but with an additional branch that sends duplicate output.
Diagrammatically, this has the shape of a capital letter T (see Figure 44-5). In addi-
tion to the purpose described here, tee is also useful for debugging pipelines and
for saving the results produced at some intervening point in a complex pipeline.
Figure 44-5: Using a FIFO and tee(1) to create a dual pipeline
ls
wc
tee sort
FIFO