Bash Redirection

Introduction

We're going to explain a few things about Bash redirection here. It's a perennial oldie-but-goodie topic that in my opinion is usually explained poorly.

Redirection is all about the manipulation, via Bash, of a command's input and output streams. Redirection makes it possible to achieve various effects that are perhaps not possible with the command alone, and to combine commands in various ways.

Operators

Redirection operators cause bash to change the standard open file configuration that it normally establishes when it processes a command.

In this standard configuration, a process inherits three open files, i.e. three file pointers, with file descriptors 0, 1, and 2, on which the file /dev/tty, i.e. the terminal keyboard/screen, is opened for reading, writing, and writing respectively. These three particular open files are referred to as stdin, stdout, and stderr respectively, and in a C program the constants stdin, stdout, and stderr contain the pointer values.

Note that it is Bash, not the command being run, that opens the files, and that it is merely convention that commands write normal output to file descriptor 1 and error output to file descriptor 2. Also, most commands that take a file argument read from file descriptor 0, i.e. stdin, i.e. the terminal keyboard, if no such argument is provided, e.g. cat, sort.

NOTE: On Ubuntu, /dev/stdin and /dev/fd/0 are symlinked to /proc/self/fd/0, which is itself symlinked to /dev/tty<n> or /dev/pts/<n>, i.e. the tty of the process; similarly for /dev/stdout and /dev/fd/1, and /dev/stderr and /dev/fd/2.

The redirection operators generally consist of a file descriptor, some symbols, and a file name. The key to understanding these operators is to recognize that the whole construct is the operator, and also that the symbols are mnemonic.

0<file        # open file (instead of /dev/tty) for reading on fd 0; the < points towards 0 indicating that fd 0 handles input 
1>file        # open file (instead of /dev/tty) for writing on fd 1; the > points away from 1 indicating that fd 1 handles output 
2>file        # open file (instead of /dev/tty) for writing on fd 2; the > points away from 2 indicating that fd 2 handles output 

1>>file       # open file (instead of /dev/tty) for appended writing on fd 1
2>>file       # open file (instead of /dev/tty) for appended writing on fd 2

1>&2          # open whatever file is opened for writing on fd 2 on fd 1 also, i.e. duplicate fd 2; the & means "and" in the sense of duplication
2>&1          # open whatever file is opened for writing on fd 1 on fd 2 also, i.e. duplicate fd 1; the & means "and" in the sense of duplication

&>file        # open file (instead of /dev/tty) for writing on fd 1 and fd 2; shortcut equivalent to 1>file 2>&1
&>>file       # open file (instead of /dev/tty) for appended writing on fd 1 and fd 2; shortcut equivalent to 1>>file 2>&1

The classic example is to count the files in the current directory using:

ls 1>temp
wc -l 0<temp

Note that a file opened for writing or appending is created if it doesn't exist - the count above will include the file temp. Also note that redirection is not limited to file descriptors 0-2, although these are most commonly used; any file descriptor can be redirected if it is known that the program uses it.

Usage

Some usage tips:

  • try to always use file descriptors; however in 0<file the 0 may be omitted; in 1>file, 1>>file, and 1>&2 the 1 may be omitted

  • don't use spaces; using spaces masks the fact that the whole construct is the operator, and it also confuses redirection with piping:

ls > file 2>&1   # confusing - how many operators? what goes with what? looks like a pipe

ls 1>file 2>&1   # clear - two operators
  • operators may be placed before or after a command; such command lines are clearer when spaces aren't used; these two command lines are equivalent:
ls 1>file

1>file ls
  • operators are evaluated left to right and the order of operators is significant when duplicating, i.e. an fd is duplicated as it exists when the operator is evaluated:
1>file 2>&1   # open file for writing on fd 1 and fd 2; fd 1 duplicated after redirection

2>&1 1>file   # open /dev/tty for writing on fd 2 and file for writing on fd 1; fd 1 duplicated before redirection

And there we are. A few things about Bash redirection
.

Currently unrated

Categories

Tags

Authors

Feeds

RSS / Atom