I/O Redirection


Nitin Venkatesh's Gravatar

Nitin Venkatesh
published May 2, 2015, 3:53 a.m.


I/O redirection can come in very handy at times when you're working on the command-line. You can redirect the source of an input to a command and the destination of the output it produces to be files, or other commands themselves.

Enough talk, let's get down to business!

First of all, the things we need to know are the streams,

  • 0 (or) stdin : Standard Input - input to a program
  • 1 (or) stdout : Standard Output - output from a program
  • 2 (or) stderr : Standard Error - error output from a program

Redirecting input (with <)

By default, the standard input is the keyboard most of the time. However, for some commands, this can be redirected with the < operator. Mostly, these are commands that accept an external file as input.

For example, instead of uniq <filename>, you could do uniq < <filename>,

$ uniq < fruits.txt

Apples
bananas
cherries
grapes

The need to use input direction is fewer when compared to the next two streams(output and error).

Redirecting output (with >)

By default, the standard output for most programs is the display screen. We could redirect this with the > operator. This comes in handy to save the output generated by a command.

For example,

$ ls -lah /home/nitin > home_file_list.txt
$ wc -l home_file_list.txt 
131 home_file_list.txt

To append the output to an existing file, we use the >> operator.

Example,

$ ls -lah /home/nitin >> home_file_list.txt
$ wc -l home_file_list.txt 
262 home_file_list.txt

Before we move on to redirecting stderr, let's take a second to talk about file descriptors.

File Descriptors

File descriptors are like a pointer sort of thing, used to refer to input/output resources. You could also assign file descriptors to different resources.

The standard streams have their default file descriptors.

  • 0 - stdin (Standard Input)
  • 1 - stdout (Standard Output)
  • 2 - stderr (Standard Error)

We'll mostly deal with the 1 and 2 file descriptors.

To redirect the output using file descriptors, we use it in the following format:

$ ls -lah . 1> output.txt

Similarly, we could redirect stderr as well,

$ ls -la /nothing 2> error.txt

$ cat error.txt 
ls: cannot access /nothing: No such file or directory

Suppressing stdout and stderr with file descriptors

Sometimes, we'd want to suppress all output a command produces (stdout and stderr). In such cases, we could pipe the output of stderr to stdout and write all stdout to a file (which is what is shown below).

Please remember that when you're doing redirection with two file descriptors, the second file descriptor has a & before it.

$ ls -lah . /nothing > all_output.txt 2>&1

$ cat all_output.txt 
ls: cannot access /nothing: No such file or directory
.:
total 60K
drwxr-xr-x 2 nitin nitin 4.0K Mar 24 10:21 .
drwxr-xr-x 5 nitin nitin 4.0K Mar 24 09:09 ..
-rw-r--r-- 1 nitin nitin    0 Mar 24 09:08 1
-rw-r--r-- 1 nitin nitin    0 Mar 24 09:08 2
-rw-r--r-- 1 nitin nitin    0 Mar 24 09:08 3
-rw-r--r-- 1 nitin nitin   54 Mar 24 10:21 all_output.txt
-rw-r--r-- 1 nitin nitin   54 Mar 24 10:19 error.txt
-rw-r--r-- 1 nitin nitin   31 Mar 24 09:25 fruits2.txt
-rw-r--r-- 1 nitin nitin   38 Mar 24 08:58 fruits.txt
-rw-r--r-- 1 nitin nitin  17K Mar 24 10:02 home_file_list.txt
-rw-r--r-- 1 nitin nitin  677 Mar 24 10:20 output.txt
-rw-r--r-- 1 nitin nitin   31 Mar 24 09:39 rev_sort.txt
-rw-r--r-- 1 nitin nitin   69 Mar 24 09:28 uniq
-rw-r--r-- 1 nitin nitin   31 Mar 24 09:37 uniq_fruits.txt

An alternative to that lengthy command is using &> , like so,

$ ls -lah . /nothing &> all_output_v2.txt

& represents both 1 and 2 so stdout and stderr get redirected. Still don't believe me? Let's verify it.

$ wc -l all_output.txt all_output_v2.txt 
  18 all_output.txt
  18 all_output_v2.txt
  36 total

Appending stdout/stderr

To append the output instead of over-writing, use the >> operator instead. Here are some examples,

$ ls -lah . /nothing &>> all_output_v2.txt
$ ls -lah . /nothing >> all_output.txt 2>&1
$ ls -lah /home/nitin >> home_file_list.txt

$ wc -l all_output.txt all_output_v2.txt home_file_list.txt 
   36 all_output.txt
   36 all_output_v2.txt
  393 home_file_list.txt
  465 total

Combining input redirectors

We can also combine the redirectors, we've seen above. Following are a few examples:

With < and >

$ uniq < fruits.txt > uniq_fruits.txt

$ cat uniq_fruits.txt 
Apples
bananas
cherries
grapes

With <,> and |

$ uniq < fruits.txt | sort -r > rev_sort.txt

$ cat rev_sort.txt 
grapes
cherries
bananas
Apples