Abstract
| Goal | Create, view, and edit text files from command output or in a text editor. |
| Objectives |
|
| Sections |
|
| Lab |
Creating, Viewing, and Editing Text Files |
After completing this section, you should be able to save output or errors to a file with shell redirection, and process command output through multiple command-line programs with pipes.
A running program, or process, needs to read input from somewhere and write output to somewhere. A command run from the shell prompt normally reads its input from the keyboard and sends its output to its terminal window.
A process uses numbered channels called file descriptors to get input and send output. All processes start with at least three file descriptors. Standard input (channel 0) reads input from the keyboard. Standard output (channel 1) sends normal output to the terminal. Standard error (channel 2) sends error messages to the terminal. If a program opens separate connections to other files, it may use higher-numbered file descriptors.
Table 5.1. Channels (File Descriptors)
| Number | Channel name | Description | Default connection | Usage |
|---|---|---|---|---|
| 0 | stdin | Standard input | Keyboard | read only |
| 1 | stdout | Standard output | Terminal | write only |
| 2 | stderr | Standard error | Terminal | write only |
| 3+ | | Other files | none | read and/or write |
I/O redirection changes how the process gets its input or output. Instead of getting input from the keyboard, or sending output and errors to the terminal, the process reads from or writes to files. Redirection lets you save messages to a file that are normally sent to the terminal window. Alternatively, you can use redirection to discard output or errors, so they are not displayed on the terminal or saved.
Redirecting stdout suppresses process output from appearing on the terminal.
As seen in the following table, redirecting only stdout does not suppress stderr error messages from displaying on the terminal.
If the file does not exist, it will be created.
If the file does exist and the redirection is not one that appends to the file, the file's contents will be overwritten.
If you want to discard messages, the special file /dev/null quietly discards channel output redirected to it and is always an empty file.
Table 5.2. Output Redirection Operators
| Usage | Explanation | Visual aid | |
|---|---|---|---|
> file | redirect stdout to overwrite a file |
| |
>> file | redirect stdout to append to a file |
| |
2> file | redirect stderr to overwrite a file |
| |
| 2> /dev/null | discard stderr error messages by redirecting to /dev/null |
| |
> file 2>&1 | redirect stdout and stderr to overwrite the same file |
| |
&> file | |||
>> file 2>&1 | redirect stdout and stderr to append to the same file |
| |
&>> file |
The order of redirection operations is important.
The following sequence redirects standard output to file and then redirects
standard error to the same place as standard output (file).
> file 2>&1
However, the next sequence does redirection in the opposite order.
This redirects standard error to the default place for standard output (the terminal window, so no change) and then redirects only standard output to file.
2>&1 > file
Because of this, some people prefer to use the merging redirection operators:
&>file | instead of | >file 2>&1 |
&>>file | instead of | >>file 2>&1 (in Bash 4 / RHEL 6 and later) |
However, other system administrators and programmers who also use other shells related to bash (known as Bourne-compatible shells) for scripting commands think that the newer merging redirection operators should be avoided, because they are not standardized or implemented in all of those shells and have other limitations.
The authors of this course take a neutral stance on this topic, and both syntaxes are likely to be encountered in the field.
Examples for Output Redirection
Many routine administration tasks are simplified by using redirection. Use the previous table to assist while considering the following examples:
Save a time stamp for later reference.
[user@host ~]$date > /tmp/saved-timestamp
Copy the last 100 lines from a log file to another file.
[user@host ~]$tail -n 100 /var/log/dmesg > /tmp/last-100-boot-messages
Concatenate four files into one.
[user@host ~]$cat file1 file2 file3 file4 > /tmp/all-four-in-one
List the home directory's hidden and regular file names into a file.
[user@host ~]$ls -a > /tmp/my-file-names
Append output to an existing file.
[user@host ~]$echo "new line of information" >> /tmp/many-lines-of-information[user@host ~]$diff previous-file current-file >> /tmp/tracking-changes-made
The next few commands generate error messages because some system directories are inaccessible to normal users. Observe as the error messages are redirected. Redirect errors to a file while viewing normal command output on the terminal.
[user@host ~]$find /etc -name passwd 2> /tmp/errors
Save process output and error messages to separate files.
[user@host ~]$find /etc -name passwd > /tmp/output 2> /tmp/errors
Ignore and discard error messages.
[user@host ~]$find /etc -name passwd > /tmp/output 2> /dev/null
Store output and generated errors together.
[user@host ~]$find /etc -name passwd &> /tmp/save-both
Append output and generated errors to an existing file.
[user@host ~]$find /etc -name passwd >> /tmp/save-both 2>&1
A pipeline is a sequence of one or more commands separated by the pipe character (|). A pipe connects the standard output of the first command to the standard input of the next command.
Pipelines allow the output of a process to be manipulated and formatted by other processes before it is output to the terminal. One useful mental image is to imagine that data is "flowing" through the pipeline from one process to another, being altered slightly by each command in the pipeline through which it flows.
Pipelines and I/O redirection both manipulate standard output and standard input. Redirection sends standard output to files or gets standard input from files. Pipes send the standard output from one process to the standard input of another process.
Pipeline Examples
This example takes the output of the ls command and uses less to display it on the terminal one screen at a time.
[user@host ~]$ls -l /usr/bin | less
The output of the ls command is piped to wc -l, which counts the number of lines received from ls and prints that to the terminal.
[user@host ~]$ls | wc -l
In this pipeline, head will output the first 10 lines of output from ls -t, with the final result redirected to a file.
[user@host ~]$ls -t | head -n 10 > /tmp/ten-last-changed-files
Pipelines, Redirection, and the tee Command
When redirection is combined with a pipeline, the shell sets up the entire pipeline first, then it redirects input/output. If output redirection is used in the middle of a pipeline, the output will go to the file and not to the next command in the pipeline.
In this example, the output of the ls command goes to the file, and less displays nothing on the terminal.
[user@host ~]$ls > /tmp/saved-output | less
The tee command overcomes this limitation. In a pipeline, tee copies its standard input to its standard output and also redirects its standard output to the files named as arguments to the command. If you imagine data as water flowing through a pipeline, tee can be visualized as a "T" joint in the pipe which directs output in two directions.
Pipeline Examples Using the tee Command
This example redirects the output of the ls command to the file and passes it to less to be displayed on the terminal one screen at a time.
[user@host ~]$ls -l | tee /tmp/saved-output | less
If tee is used at the end of a pipeline, then the final output of a command can be saved and output to the terminal at the same time.
[user@host ~]$ls -t | head -n 10 | tee /tmp/ten-last-changed-files
Standard error can be redirected through a pipe, but the merging redirection operators (&> and &>>) cannot be used to do this.
The following is the correct way to redirect both standard output and standard error through a pipe:
[user@host ~]$ find -name / passwd 2>&1 | lessinfo bash (The GNU Bash Reference Manual)
Section 3.2.2: Pipelines
Section 3.6: Redirections
info coreutils 'tee invocation' (The GNU coreutils Manual)
Section 17.1: Redirect output to multiple files or processes
bash(1), cat(1), head(1), less(1), mail(1), tee(1), tty(1), wc(1) man pages