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-3). 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 screen 1 and describe how you can cause the shell to redirect this output to another file.
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 292 (bash) and page 389 (tcsh) for more information on redirecting standard error.
The Screen as a File
Chapter 4 introduced 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-4). 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.
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 (that is, 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). Figure 5-5 shows this exchange.
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.
Figure 5-4 By default, standard input comes from the keyboard, and standard output goes to the screen
Figure 5-5 The cat utility copies standard input to standard output
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-6). The syntax of a command line that redirects output is
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.
Figure 5-7 uses cat to demonstrate output redirection. This figure contrasts with Figure 5-5, where standard input and standard output are associated with the keyboard and screen. The input in Figure 5-7 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.
Figure 5-6 Redirecting standard output
After giving the command and typing the text shown in Figure 5-7, 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.
Figure 5-7 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.
Figure 5-8 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 supply_orders. The final cat command shows that supply_orders contains the contents of the three original files.
Figure 5-7 cat with its output redirected
Figure 5-8 Using cat to catenate files
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-9). The syntax of a command line that redirects input is
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.
Figure 5-10 shows cat with its input redirected from the supply_orders file created in Figure 5-8 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.
Figure 5-9 Redirecting standard input
Figure 5-10 Redirecting and appending output
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. Under tcsh use set noclobber and unset noclobber. With noclobber set, if you redirect output to an existing file, theshell displays an error message and does not execute the command. Run under bash and tcsh, the following examples create a file using touch, set noclobber, attempt to redirect the output from echo to the newly created file, unset noclobber, and perform 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
tcsh $ touch tmp tcsh $ set noclobber tcsh $ echo "hi there" > tmp tmp: File exists. tcsh $ unset noclobber tcsh $ echo "hi there" > tmp
You can override noclobber by putting a pipe symbol (tcsh uses an exclamation point) 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 pipe 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
For more information on using noclobber under tcsh, refer to page 407.
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.
Figure 5-10 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.
/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
A pipeline consists of one or more commands separated by a pipe symbol (|). The shell connects standard output (and optionally standard error) of the command preceding the pipe symbol to standard input of the command following the pipe 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
Figure 5-11 cat with its input redirected
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
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; page 1014) utility takes its input from standard input only. In its simplest usage tr has the 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.
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 commands in Figure 5-12 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.
The commands in Figure 5-13 redirect the output from the who utility to temp and then display this file in sorted order. The sort utility (page 58) 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 in Figure 5-13 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 Figure 5-13 yields the same result.
Figure 5-12 A pipeline
Figure 5-13 Using a temporary file to store intermediate results
Figure 5-14 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.
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 (pages 56 and 853) using a pipeline. The grep utility displays the line containing the string you specify—sam in the following example.
$ who | grep sam sam tty1 2018-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 53).
$ 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.
Figure 5-14 A pipeline doing the work of a temporary file
Figure 5-15 tee sends its output to a file and to standard output
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 pipe symbol to connect standard output of one command to standard input of the filter. Another pipe 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 pipe 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.
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. In Figure 5-15 the output of who is sent 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.