The Unix I/O scheme is based on two dazzlingly simple ideas.
First, Unix file I/O takes the form of arbitrarily
long sequences of characters (bytes). In contrast, file systems
of older vintage have more complicated I/O schemes (e.g., "block,"
"record," "card image," etc.).
Second, everything on the system that
produces or accepts data is treated as a file; this includes
hardware devices like disk drives and terminals. Older systems
treated every device differently. Both of these ideas have made
systems programmers' lives much more pleasant.
1.7.1. Standard I/O
By convention, each Unix program has a single
way of accepting input called standard input, a single way
of producing output called standard output, and a single way
of producing error messages called standard error output,
usually shortened to standard error.
Of course, a program can have other input and output sources as well,
as we will see in Chapter 7.
Standard I/O was the first scheme of its kind that was designed
specifically for interactive users, rather than
the older batch style of use that usually involved decks of
punch-cards. Since the Unix shell provides the user interface,
it should come as no surprise that standard I/O was designed to
fit in very neatly with the shell.
All shells handle standard I/O in basically the same way.
Each program that you invoke has all three standard I/O channels
set to your terminal or workstation window, so that standard input is
your keyboard, and standard output and error are your screen or
window. For example, the mail utility prints messages
to you on the standard output, and when you use it to send messages
to other users, it accepts your input on the standard input.
This means that you view
messages on your screen and type new ones in on your keyboard.
When necessary, you can redirect
input and output to come from or go to a file instead. If you want to
send the contents of a preexisting file to someone as mail,
you redirect mail's standard input so that it reads from
that file instead of your keyboard.
You can also hook up programs into a pipeline, in which the standard output
of one program feeds directly into the standard input
of another; for example,
you could feed mail output
directly to the lp program so that messages are printed
instead of shown on the screen.
This makes it possible to use Unix utilities as
building blocks for bigger programs. Many Unix utility programs
are meant to be used in this way: they each perform
a specific type of filtering operation on input text.
Although this isn't a textbook on Unix utilities, they are
essential to productive shell use. The more popular filtering
utilities are listed in
Table 1-5.
Table 1-5. Popular Unix data filtering utilities
Utility |
Purpose |
cat |
Copy input to output |
grep |
Search for strings in the input |
sort |
Sort lines in the input |
cut |
Extract columns from input |
sed |
Perform editing operations on input |
tr |
Translate characters in the input to other characters |
You may have used some of these before and noticed that they take
names of input files as arguments and produce output on standard output.
You may not know, however, that all of them (and most other
Unix utilities) accept input from standard input if you omit
the argument.[13]
For example, the most basic utility is cat, which simply
copies its input to its output. If you type cat with a
filename argument, it will print out the contents of that file
on your screen. But if you invoke it with no
arguments, it will read standard input and copy it to standard
output. Try it: cat will wait for you to type a line of
text; when you type ENTER, cat will parrot the text back at you. To stop the
process, hit CTRL-D at the beginning of a line (see
below for
what this character means). You will see ^D when you
type CTRL-D. Here's what this should look like:
$ cat
Here is a line of text.
Here is a line of text.
This is another line of text.
This is another line of text.
^D
$