Redirection: >, >>, 2> and <

Bash · Essentials · 10 min

Saving output, logging errors and feeding files into commands are everyday shell tasks.

Every process starts with three open file descriptors: 0 standard input, 1 standard output, 2 standard error. By default all three are the terminal. Redirection reconnects them before the command starts:

  • > file writes stdout to a file, truncating it first; >> file appends.
  • 2> file sends stderr to a file; 2>> file appends.
  • 2>&1 makes fd 2 point wherever fd 1 currently points; &> file is bash shorthand for "both to file".
  • < file feeds the file to stdin.
  • /dev/null discards whatever is written to it.

Redirections are processed left to right, which makes order matter: cmd > out.txt 2>&1 sends both streams to the file, while cmd 2>&1 > out.txt first points stderr at the terminal (where stdout was at that moment) and only then moves stdout.

Keeping errors on stderr is a convention worth following in your own scripts too: echo "error: missing file" >&2. Then a caller can redirect your normal output to a file and still see the errors.

Beware sort data.txt > data.txt: the shell truncates the file before sort reads it, leaving it empty. Write to a temporary file and move it, or use sponge from moreutils. set -o noclobber makes > refuse to overwrite existing files.

Example

cd "$(mktemp -d)"
echo "first" > out.txt        # create or truncate
echo "second" >> out.txt      # append
cat out.txt                   # first / second
ls /nope 2> err.txt           # the error goes to the file
cat err.txt                   # ls: cannot access '/nope': No such file or directory
ls /tmp /nope > all.txt 2>&1  # both streams into the file
ls /tmp /nope &> all.txt      # bash shorthand for the same
wc -l < out.txt               # 2  (stdin from a file: no name printed)
ls /nope 2>/dev/null || echo "quietly failed"   # quietly failed
echo "error: something broke" >&2               # write to stderr

Remember

  • fd 0 stdin, 1 stdout, 2 stderr; > truncates, >> appends
  • cmd > file 2>&1 captures both; order of redirections matters
  • Send your own error messages to >&2

Watch out for

  • sort f > f empties the file: the shell truncates it before sort reads it.

Check yourself

  1. Which line writes both stdout and stderr of cmd into log.txt?
  2. What does `wc -l < notes.txt` print compared with `wc -l notes.txt`?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: www.gnu.org/software/bash/manual/bash.html#Redirections