Related Content: CS604 - VU Lectures, Handouts, PPT Slides, Assignments, Quizzes, Papers & Books of Operating Systems
Linux redirection features can be used to detach the default files from stdin, stdout, and
stderr and attach other files with them for a single execution of a command. The act of
detaching defaults files from stdin, stdout, and stderr and attaching other files with them
is known as input, output, and error redirection. In this section, we show the syntax,
semantics, and examples of I/O and error redirection.
Here is the syntax for input redirection:
command < input-file
or
command 0< input-file
With this command syntax, keyboard is detached from stdin of ‘command’ and ‘inputfile’ is attached to it, i.e., ‘command’ reads input from ‘input-file’ and not keyboard. Note that 0< operator cannot be used with the C and TC shells. Here is an example use of input redirection. In these examples, the cat and grep commands read input from the Phones file and not from keyboard.
$ cat < Phones
[ contents of Phones ]
$ grep “Nauman” < Phones
[ output of grep ]
$
Here is the syntax for output redirection:
command > output-file
or
command 1> output-file
With this command syntax, the display screen is detached from stdout and ‘output-file’ is
attached to it, i.e., ‘command’ sends output to ‘output-file’ and not the display screen.
Note that 1> operator cannot be used with the C and TC shells. Here is an example use of
input redirection. In these examples, the cat, grep, and find commands send their
outputs to the Phones, Ali.Phones, and foo.log files, respectively, and not to the display
screen.
$ cat > Phones
[ your input ]
<Ctrl-D>
$ grep “Ali” Phones > Ali.phones
[ output of grep ]
$ find ~ -name foo -print > foo.log
[ error messages ]
$
Here is the syntax for error redirection:
command 2> error-file
With this command syntax, the display screen is detached from stderr and ‘error-file’ is
attached to it, i.e., error messages are sent to ‘error-file’ and not the display screen. Note
that 2> cannot be used under C and TC shells. The following are a few examples of error
redirection. In these examples, the first find command sends its error messages to the
errors file and the second find command sends its error messages to the /dev/null file.
The ls command sends its error messages to the error.log file and not to the display
screen.
$ find ~ -name foo -print 2> errors
[ output of the find command ]
$ ls -l foo 2> error.log
[ output of the find command ]
$ cat error.log
ls: foo: No such file or directory
$ find / -name ls -print 2> /dev/null
/bin/ls
$
A named pipe (also called a named FIFO, or just FIFO) is a pipe whose access point is a
file kept on the file system. By opening this file for reading, a process gets access to the
FIFO for reading. By opening the file for writing, the process gets access to the FIFO for
writing. By default, a FIFO is opened for blocking I/O. This means that a process reading
from a FIFO blocks until another process writes some data in the FIFO. The same goes
the other way around. Unnamed pipes can only be used between processes that have an
ancestral relationship. And they are temporary; they need to be created every time and are
destroyed when the corresponding processes exit. Named pipes (FIFOs) overcome both
of these limitations. Figure 10.1 shows two unrelated processes, P1 and P2,
communicating with each other using a FIFO.
Named pipes are created via the mknod() system call or mkfifo() C library call or by the mkfifo command. Here is the synopsis of the mknod() system call.
#include <sys/types.h>
#include <sys/stat.h>
int mknod (const char *path, mode_t mode, dev_t dev);
The mknod() call is normally used for creating special (i.e., device) files but it can be used to create FIFOs too. The ‘mode’ argument should be permission mode OR-ed with S_IFIFO and ‘dev’ is set to 0 for creating a FIFO. As is the case with all system calls in UNIX/Linux, mknod() returns –1 on failure and errno is set accordingly. Some of the reasons for this call to fail are:
Here is the synopsis of the mkfifo() library call.
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo (const char *path, mode_t mode)
The argument path is for the name and path of the FIFO created, where was the argument mode is for specifying the file permissions for the FIFO. The specification of the mode argument for this function is the same as for the open(). Once we have created a FIFO using mkfifo(), we open it using open(). In fact, the normal file I/O system calls (close(), read(), write(), unlink(), etc.) all works with FIFOs. Since mkfifo() invokes the mknod() system call, the reasons for its failure are pretty much the same as for the mknod() call given above.
Unlike a pipe, a FIFO must be opened before using it for communication. A write to a FIFO that no process has opened for reading results in a SIGPIPE signal. When the last process to write to a FIFO closes it, an EOF is sent to the reader. Multiple processes can write to a FIFO are atomic writes to prevent interleaving of multiple writes.
Two common uses of FIFOs are:
In client-server software designed for use on the same machine, the server process creates a “well-known” FIFO. Clients communicate send their requests to the server process via the well-known FIFO. Server sends its response to a client via the clientspecific FIFO that each client creates and informs the server process about it. Figure 10.2 shows the diagrammatic view of such a software model.
On the command line, mkfifo may be used as shown in the following session. As shown in Figure 10.3, the semantics of this session are that prog1 reads its inputs from infile and its output is sent to prog2 and prog3.
$ mkfifo fifo1
$ prog3 < fifo1 &
$ prog1 < infile | tee fifo1 | prog2
[ Output ]
$
In the following session, we demonstrate the command line use of FIFOs. The semantics of this session are shown in Figure 10.4. The output of the second command line is the number of lines in the ls.dat file containing ls (i.e., the number of lines in the manual page of the ls command containing the string ls) and the output of the third command line is the number of lines in the ls.dat file (i.e., the number of lines in the manual page for the ls command).
$ man ls > ls.dat
$ cat < fifo1 | grep ls | wc -l &
[1] 21108
$ sort < ls.dat | tee fifo1 | wc -l
31
528
$