Bookmark this page

Chapter 4. Creating, Viewing, and Editing Text Files

Abstract

Goal To create, view, and edit text files from command output or in an editor.
Objectives

  • Redirect the text output of a program to a file or to another program.

  • Edit existing text files and create new files from the shell prompt with a text editor.

  • Copy text from a graphical window to a text file using a text editor running in the graphical environment.

Sections
  • Redirecting Output to a File or Program (and Practice)

  • Editing Text Files from the Shell Prompt (and Practice)

  • Editing Text Files with a Graphical Editor (and Practice)

Lab
  • Creating, Viewing, and Editing Text Files

Redirecting Output to a File or Program

Describing how program output is displayed, controlled, and saved effectively.

Objectives

After completing this section, students should be able to:

  • Describe the technical terms standard input, standard output, and standard error.

  • Use redirection characters to control output to files.

  • Use piping to control output to other programs.

Standard input, standard output, and standard error

Redirecting output to a file or program

A running program, or process, needs to read input from somewhere and write output to the screen or to files. 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 will have at least three file descriptors to start with. 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.

Figure 4.1: Process I/O channels (file descriptors)

Table 4.1. Channels (File Descriptors)

NumberChannel nameDescriptionDefault connectionUsage
0stdinStandard inputKeyboardread only
1stdoutStandard outputTerminalwrite only
2stderrStandard errorTerminalwrite only
3+filenameOther filesnoneread and/or write

Redirecting output to a file

I/O redirection replaces the default channel destinations with file names representing either output files or devices. Using redirection, process output and error messages normally sent to the terminal window can be captured as file contents, sent to a device, or discarded.

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. The special file /dev/null quietly discards channel output redirected to it and is always an empty file.

Table 4.2. Output Redirection Operators

UsageExplanationVisual aid
>fileredirect stdout to overwrite a file
>>fileredirect stdout to append to a file
2>fileredirect stderr to overwrite a file
2>/dev/nulldiscard stderr error messages by redirecting to /dev/null
>file  2>&1redirect stdout and stderr to overwrite the same file
&>file
>>file  2>&1redirect stdout and stderr to append to the same file
&>>file

Important

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:

&>fileinstead of>file 2>&1
&>>fileinstead 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 ("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 timestamp for later reference.

    [student@desktopX ~]$ date > /tmp/saved-timestamp

  • Copy the last 100 lines from a log file to another file.

    [student@desktopX ~]$ tail -n 100 /var/log/dmesg > /tmp/last-100-boot-messages

  • Concatenate four files into one.

    [student@desktopX ~]$ cat file1 file2 file3 file4 > /tmp/all-four-in-one

  • List the home directory's hidden and regular file names into a file.

    [student@desktopX ~]$ ls -a > /tmp/my-file-names

  • Append output to an existing file.

    [student@desktopX ~]$ echo "new line of information" >> /tmp/many-lines-of-information
    [student@desktopX ~]$ diff previous-file current-file >> /tmp/tracking-changes-made

  • In the next examples, errors are generated since normal users are denied access to system directories. Redirect errors to a file while viewing normal command output on the terminal.

    [student@desktopX ~]$ find /etc -name passwd 2> /tmp/errors

  • Save process output and error messages to separate files.

    [student@desktopX ~]$ find /etc -name passwd > /tmp/output 2> /tmp/errors

  • Ignore and discard error messages.

    [student@desktopX ~]$ find /etc -name passwd > /tmp/output 2> /dev/null

  • Store output and generated errors together.

    [student@desktopX ~]$ find /etc -name passwd &> /tmp/save-both

  • Append output and generated errors to an existing file.

    [student@desktopX ~]$ find /etc -name passwd >> /tmp/save-both 2>&1

Constructing pipelines

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.

Figure 4.8: Process I/O piping

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 in slight ways by each command in the pipeline through which it passes.

Note

Pipelines and I/O redirection both manipulate standard output and standard input. Redirection sends standard output to or gets standard input from files. Pipes send standard output to or get standard input from 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.

[student@desktopX ~]$ 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.

[student@desktopX ~]$ 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.

[student@desktopX ~]$ ls -t | head -n 10 > /tmp/ten-last-changed-files

Pipelines, redirection, and tee

When redirection is combined with a pipeline, the shell first sets up the entire pipeline, then it redirects input/output. What this means is that 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 will go to the file, and less will display nothing on the terminal.

[student@desktopX ~]$ ls > /tmp/saved-output | less

The tee command is used to work around this. In a pipeline, tee will copy its standard input to its standard output and will also redirect its standard output to the files named as arguments to the command. If data is imagined to be like water flowing through a pipeline, tee can be visualized as a "T" joint in the pipe which directs output in two directions.

Figure 4.9: Process I/O piping with tee

Pipeline examples using the tee command

This example will redirect the output of the ls command to the file and will pass it to less to be displayed on the terminal a screen at a time.

[student@desktopX ~]$ 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.

[student@desktopX ~]$ ls -t | head -n 10 | tee /tmp/ten-last-changed-files

This more sophisticated example takes advantage of the fact that a special device file exists that represents the terminal. The name of the device file for a particular terminal can be determined by running the tty command at its shell prompt. Then tee can be used to redirect output to that file to display it on the terminal window, while standard output can be passed to some other program through a pipe. In this case, mail will e-mail the output to student@desktop1.example.com.

[student@desktopX ~]$ tty
/dev/pts/0
[student@desktopX ~]$ ls -l | tee /dev/pts/0 | mail student@desktop1.example.com

Important

Standard error can be redirected through a pipe, but the merging redirection operators (&> and &>>) can not be used to do this.

The following is the correct way to redirect both standard output and standard error through a pipe:

[student@desktopX ~]$ find -name / passwd 2>&1 | less

References

info 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

Revision: rh124-7-1b00421