Standard Input and Standard Output
Standard output is a place to which a program can send information (e.g., text). The program never “knows” where the information it sends to standard output is going (Figure 5-2). The information can go to a printer, an ordinary file, or the screen. The following sections show that by default the shell directs standard output from a command to the screen1 and describe how you can cause the shell to redirect this output to another file.
Figure 5-2 The command does not know where standard input comes from or where standard output and standard error go
Standard input is a place a program gets information from; by default, the shell directs standard input from the keyboard. As with standard output the program never “knows” where the information comes from. The following sections explain how to redirect standard input to a command so it comes from an ordinary file instead of from the keyboard.
In addition to standard input and standard output, a running program has a place to send error messages: standard error. By default, the shell directs standard error to the screen. Refer to page 339 for more information on redirecting standard error.
The Screen as a File
Device file
Chapter 6 discusses ordinary files, directory files, and hard and soft links. Linux has an additional type of file: a device file. A device file resides in the file structure, usually in the /dev directory, and represents a peripheral device, such as a terminal, printer, or disk drive.
The device name the who utility displays following a username is the filename of the terminal that user is working on. For example, when who displays the device name pts/4, the pathname of the terminal is /dev/pts/4. When you work with multiple windows, each window has its own device name. You can also use the tty utility to display the name of the device that you give the command from. Although you would not normally have occasion to do so, you can read from and write to this file as though it were a text file. Reading from the device file that represents the terminal you are using reads what you enter on the keyboard; writing to it displays what you write on the screen.
The Keyboard and Screen as Standard Input and Standard Output
After you log in, the shell directs standard output of commands you enter to the device file that represents the terminal (Figure 5-3). Directing output in this manner causes it to appear on the screen. The shell also directs standard input to come from the same file, so commands receive as input anything you type on the keyboard.
Figure 5-3 By default, standard input comes from the keyboard, and standard output goes to the screen
cat
The cat utility provides a good example of the way the keyboard and screen function as standard input and standard output, respectively. When you run cat, it copies a file to standard output. Because the shell directs standard output to the screen, cat displays the file on the screen.
Up to this point cat has taken its input from the filename (argument) you specify on the command line. When you do not give cat an argument (i.e., when you give the command cat followed immediately by RETURN), cat takes its input from standard input. Thus, when called without an argument, cat copies standard input to standard output, one line at a time.
To see how cat works, type cat and press RETURN in response to the shell prompt. Nothing happens. Enter a line of text and press RETURN. The same line appears just under the one you entered. The cat utility is working. Because the shell associates cat’s standard input with the keyboard and cat’s standard output with the screen, when you type a line of text cat copies the text from standard input (the keyboard) to standard output (the screen). The next example shows this exchange.
$
cat
This is a line of text.
This is a line of text.
Cat keeps copying lines of text
Cat keeps copying lines of text
until you press CONTROL-D at the beginning
until you press CONTROL-D at the beginning
of a line.
of a line.
CONTROL-D
$
CONTROL-D signals EOF
The cat utility keeps copying text until you enter CONTROL-D on a line by itself. Pressing CONTROL-D causes the tty device driver to send an EOF (end of file) signal to cat. This signal indicates to cat that it has reached the end of standard input and there is no more text for it to copy. The cat utility then finishes execution and returns control to the shell, which displays a prompt.
Redirection
The term redirection encompasses the various ways you can cause the shell to alter where standard input of a command comes from and where standard output goes to. By default, the shell associates standard input and standard output of a command with the keyboard and the screen. You can cause the shell to redirect standard input or standard output of any command by associating the input or output with a command or file other than the device file representing the keyboard or the screen. This section demonstrates how to redirect input/output from/to text files and utilities.
Redirecting Standard Output
The redirect output symbol (>) instructs the shell to redirect the output of a command to the specified file instead of to the screen (Figure 5-4). The syntax of a command line that redirects output is
Figure 5-4 Redirecting standard output
- command [arguments] > filename
where command is any executable program (e.g., an application program or a utility), arguments are optional arguments, and filename is the name of the ordinary file the shell redirects the output to.
Using cat tocreate a file
The next example uses cat to demonstrate output redirection. This example contrasts with the example on page 161, where standard input and standard output are associated with the keyboard and screen. The input in the following example comes from the keyboard. The redirect output symbol on the command line causes the shell to associate cat’s standard output with the sample.txt file specified following this symbol.
$
cat > sample.txt
This text is being entered at the keyboard and
cat is copying it to a file.
Press CONTROL-D to indicate the
end of file.
CONTROL-D
$
After giving the command and typing the text shown in the previous example, the sample.txt file contains the text you entered. You can use cat with an argument of sample.txt to display this file. The next section shows another way to use cat to display the file.
The previous example shows that redirecting standard output from cat is a handy way to create a file without using an editor. The drawback is that once you enter a line and press RETURN, you cannot edit the text until after you finish creating the file. While you are entering a line, the erase and kill keys work to delete text on that line. This procedure is useful for creating short, simple files.
The next example shows how to run cat and use the redirect output symbol to catenate (join one after the other—the derivation of the name of the cat utility) several files into one larger file. The first three commands display the contents of three files: stationery, tape, and pens. The next command shows cat with three filenames as arguments. When you call it with more than one filename, cat copies the files, one at a time, to standard output. This command redirects standard output to the file named supply_orders. The final cat command shows that supply_orders contains the contents of the three original files.
$
cat stationery
2,000 sheets letterhead ordered: October 7
$
cat tape
1 box masking tape ordered: October 14
5 boxes filament tape ordered: October 28
$
cat pens
12 doz. black pens ordered: October 4
$
cat stationery tape pens > supply_orders
$
cat supply_orders
2,000 sheets letterhead ordered: October 7
1 box masking tape ordered: October 14
5 boxes filament tape ordered: October 28
12 doz. black pens ordered: October 4
Redirecting Standard Input
Just as you can redirect standard output, so you can redirect standard input. The redirect input symbol (<) instructs the shell to redirect a command’s input to come from the specified file instead of from the keyboard (Figure 5-5). The syntax of a command line that redirects input is
Figure 5-5 Redirecting standard input
- command [arguments] < filename
where command is any executable program (such as an application program or a utility), arguments are optional arguments, and filename is the name of the ordinary file the shell redirects the input from.
The next example shows cat with its input redirected from the supply_orders file created in the previous example and standard output going to the screen. This setup causes cat to display the supply_orders file on the screen. The system automatically supplies an EOF signal at the end of an ordinary file.
$
cat < supply_orders
2,000 sheets letterhead ordered: October 7
1 box masking tape ordered: October 14
5 boxes filament tape ordered: October 28
12 doz. black pens ordered: October 4
Utilities that take input from a file or standard input
Giving a cat command with input redirected from a file yields the same result as giving a cat command with the filename as an argument. The cat utility is a member of a class of utilities that function in this manner. Other members of this class of utilities include lpr, sort, grep, and Perl. These utilities first examine the command line that called them. If the command line includes a filename as an argument, the utility takes its input from the specified file. If no filename argument is present, the utility takes its input from standard input. It is the utility or program—not the shell or operating system—that functions in this manner.
noclobber: Prevents Overwriting Files
The shell provides the noclobber feature, which prevents you from overwriting a file using redirection. Enable this feature by setting noclobber using the command set –o noclobber. The same command with +o unsets noclobber. With noclobber set, if you redirect output to an existing file, the shell displays an error message and does not execute the command. The following example creates a file using touch, sets noclobber, attempts to redirect the output from echo to the newly created file, unsets noclobber, and performs the same redirection:
$
touch tmp
$
set -o noclobber
$
echo "hi there" > tmp
-bash: tmp: cannot overwrite existing file
$
set +o noclobber
$
echo "hi there" > tmp
You can override noclobber by putting a pipeline symbol after the redirect symbol (>|). In the following example, the user creates a file by redirecting the output of date. Next the user sets the noclobber variable and redirects output to the same file again. The shell displays an error message. Then the user places a pipeline symbol after the redirect symbol, and the shell allows the user to overwrite the file.
$
date > tmp2
$
set -o noclobber
$
date > tmp2
-bash: tmp2: cannot overwrite existing file
$
date >| tmp2
Appending Standard Output to a File
The append output symbol (>>) causes the shell to add new information to the end of a file, leaving existing information intact. This symbol provides a convenient way of catenating two files into one. The following commands demonstrate the action of the append output symbol. The second command accomplishes the catenation described in the preceding caution box:
$
cat orange
this is orange
$
cat pear >> orange
$
cat orange
this is orange
this is pear
The first command displays the contents of the orange file. The second command appends the contents of the pear file to the orange file. The final command displays the result.
The next example shows how to create a file that contains the date and time (the output from date), followed by a list of who is logged in (the output from who). The first command in the example redirects the output from date to the file named whoson. Then cat displays the file. The next command appends the output from who to the whoson file. Finally cat displays the file containing the output of both utilities.
$
date > whoson
$
cat whoson
Wed Mar 27 14:31:18 PST 2013
$
who >> whoson
$
cat whoson
Wed Mar 27 14:31:18 PST 2013
sam tty1 2013-03-27 05:00(:0)
max pts/4 2013-03-27 12:23(:0.0)
max pts/5 2013-03-27 12:33(:0.0)
zach pts/7 2013-03-26 08:45 (172.16.192.1)
/dev/null: Making Data Disappear
The /dev/null device is a data sink, commonly referred to as a bit bucket. You can redirect output you do not want to keep or see to /dev/null, and the output will disappear without a trace:
$
echo "hi there" > /dev/null
$
Reading from /dev/null yields a null string. The following command truncates the file named messages to zero length while preserving the ownership and permissions of the file:
$
ls -lh messages
-rw-rw-r--. 1 sam pubs 125K 03-16 14:30 messages
$
cat /dev/null > messages
$
ls -lh messages
-rw-rw-r--. 1 sam pubs 0 03-16 14:32 messages
See also page 481.
Pipelines
A pipeline consists of one or more commands separated by a pipeline symbol ( |). The shell connects standard output (and optionally standard error) of the command preceding the pipeline symbol to standard input of the command following the pipeline symbol. A pipeline has the same effect as redirecting standard output of one command to a file and then using that file as standard input to another command. A pipeline does away with separate commands and the intermediate file. The syntax of a pipeline is
- command_a [arguments] | command_b [arguments]
The preceding command line uses a pipeline to effect the same result as the following three commands:
- command_a [arguments] > temp command_b [arguments] < temp rm temp
In the preceding sequence of commands, the first line redirects standard output from command_a to an intermediate file named temp. The second line redirects standard input for command_b to come from temp. The final line deletes temp. The pipeline syntax is not only easier to type but also is more efficient because it does not create a temporary file.
Examples of Pipelines
tr
You can include in a pipeline any utility that accepts input either from a file specified on the command line or from standard input. You can also include utilities that accept input only from standard input. For example, the tr (translate) utility takes its input from standard input only. In its simplest usage tr has the following syntax:
- tr string1 string2
The tr utility accepts input from standard input and looks for characters that match one of the characters in string1. Upon finding a match, it translates the matched character in string1 to the corresponding character in string2. That is, the first character in string1 translates into the first character in string2, and so forth. The tr utility sends its output to standard output. In both of the following tr commands, tr displays the contents of the abstract file with the letters a, b, and c translated into A, B, and C, respectively:
$
cat abstract
I took a cab today!
$
cat abstract | tr abc ABC
I took A CAB todAy!
$
tr abc ABC < abstract
I took A CAB todAy!
The tr utility does not change the contents of the original file; it cannot change the original file because it does not “know” the source of its input.
lpr
The lpr (line printer) utility accepts input from either a file or standard input. When you type the name of a file following lpr on the command line, it places that file in the print queue. When you do not specify a filename on the command line, lpr takes input from standard input. This feature enables you to use a pipeline to redirect input to lpr. The first set of the following commands shows how you can use ls and lpr with an intermediate file (temp) to send a list of the files in the working directory to the printer. If the temp file exists, the first command overwrites its contents. The second set of commands uses a pipeline to send the same list (with the exception of temp) to the printer.
$
ls > temp
$
lpr temp
$
rm temp
or
$
ls | lpr
sort
The commands in next example redirect the output from the who utility to temp and then display this file in sorted order. The sort utility (page 247) takes its input from the file specified on the command line or, when a file is not specified, from standard input; it sends its output to standard output. The sort command line takes its input from standard input, which is redirected (<) to come from temp. The output sort sends to the screen lists the users in sorted (alphabetical) order. Because sort can take its input from standard input or from a file named on the command line, omitting the < symbol from the command line yields the same result.
$
who > temp
$
sort < temp
max pts/4 2013-03-24 12:23
max pts/5 2013-03-24 12:33
sam tty1 2013-03-24 05:00
zach pts/7 2013-03-23 08:45
$
rm temp
The next example achieves the same result without creating the temp file. Using a pipeline, the shell redirects the output from who to the input of sort. The sort utility takes input from standard input because no filename follows it on the command line.
$
who | sort
max pts/4 2013-03-24 12:23
max pts/5 2013-03-24 12:33
sam tty1 2013-03-24 05:00
zach pts/7 2013-03-23 08:45
grep
When many people are using the system and you want information about only one of them, you can send the output from who to grep (page 240) using a pipeline. The grep utility displays the line containing the string you specify—sam in the following example:
$
who | grep sam
sam tty1 2013-03-24 05:00
less and more
Another way of handling output that is too long to fit on the screen, such as a list of files in a crowded directory, is to use a pipeline to send the output through less or more (both on page 228).
$
ls | less
The less utility displays text one screen at a time. To view another screen of text, press the SPACE bar. To view one more line, press RETURN. Press h for help and q to quit.
Filters
A filter is a command that processes an input stream of data to produce an output stream of data. A command line that includes a filter uses a pipeline symbol to connect standard output of one command to standard input of the filter. Another pipeline symbol connects standard output of the filter to standard input of another command. Not all utilities can be used as filters.
In the following example, sort is a filter, taking standard input from standard output of who and using a pipeline symbol to redirect standard output to standard input of lpr. This command line sends the sorted output of who to the printer:
$
who | sort | lpr
The preceding example demonstrates the power of the shell combined with the versatility of Linux utilities. The three utilities who, sort, and lpr were not designed to work with one another, but they all use standard input and standard output in the conventional way. By using the shell to handle input and output, you can piece standard utilities together on the command line to achieve the results you want.
tee
The tee utility copies its standard input both to a file and to standard output. This utility is aptly named: It takes a single stream of input and sends the output in two directions. The next example sends the output of who via a pipeline to standard input of tee. The tee utility saves a copy of standard input in a file named who.out and also sends a copy to standard output. Standard output of tee goes via a pipeline to standard input of grep, which displays only those lines containing the string sam. Use tee with the –a (append) option to cause it to append to a file instead of overwriting it.
$
who | tee who.out | grep sam
sam tty1 2013-03-24 05:00
$ cat who.out
sam tty1 2013-03-24 05:00
max pts/4 2013-03-24 12:23
max pts/5 2013-03-24 12:33
zach pts/7 2013-03-23 08:45