Output redirection and pipelines
The shell sends a command's input and output to a file or another command — >, >>, 2>&1, /dev/null, the | pipe.
Cheat sheet
10 commands Printable version-
cmd > out.txtoutput to a file (overwrite) -
cmd >> out.txtoutput appended to a file -
cmd 2> err.txterrors to a file -
cmd > all.txt 2>&1output and errors in one file -
cmd &> all.txtthe same, shorter (bash) -
cmd 2>/dev/nullthrow errors away -
cmd < in.txtinput from a file -
cmd1 | cmd2cmd1's output into cmd2's input -
cmd 2>&1 | lessinto a pipe together with errors -
cmd | tee out.txtboth to the screen and to a file
Overview
Every program starts with three open streams. A stream's number is a file descriptor:
| Stream | What it is |
|---|---|
| 0 — stdin | input: the keyboard by default |
| 1 — stdout | normal output: the screen by default |
| 2 — stderr | errors and warnings: also the screen |
A redirection tells the shell to connect a stream to a file or another command. The shell does it before the command starts, and the command doesn't know about it. That's why errors still show on screen when the output went to a file:
2>&1 means "stream 2 goes wherever stream 1 goes right now". A pipe | connects
one command's stdout to the next one's stdin; all stages run at the same time.
Recipes
7The order of 2>&1 matters
The shell reads redirections left to right. In the second line 2>&1 copies where
stdout pointed at that moment — the screen.
Process output with a chain of commands
Write to a file that needs root
sudo cmd > /etc/file won't work: your shell does the redirection without root
rights. tee runs under sudo and writes the file itself.
Multi-line input right into a command
Empty a log without deleting the file
If a process keeps the log open, rm won't free the space, but emptying will.
Find out which stage of a pipeline failed
Troubleshooting
6Permission denied with sudo … > file
Your shell opens the file, not sudo. Use | sudo tee file (or tee -a to
append).
bash: $F: ambiguous redirect
The file name in the variable has a space, or the variable is empty. Quote the
variable — > "$F" — and check that it's set.
bash: out.txt: cannot overwrite existing file
noclobber mode is on (set -o noclobber); it forbids > onto an existing file.
Overwrite explicitly with >|, or turn the mode off with set +o noclobber.
Errors didn't end up in the file
> redirects stdout only. Add 2>&1 after > file, or use &>.
grep in a pipeline doesn't find the error text
The error went to stderr, and a pipe passes only stdout. Pass both streams: cmd
2>&1 | grep text.
The file is empty after sort file > file
The shell truncated file for writing before sort read it. Write to a new file and
rename it with mv; sort also has -o file for this.
Danger zone
2> overwrites without asking
One arrow instead of two, and a log or config is replaced by a single line. Always
append with >>. An interactive shell can be protected with set -o noclobber.
2>/dev/null hides the cause
Suppressing errors is handy for the output of find /, but in scripts and while
troubleshooting the errors are the answer. Read the error first, then decide whether
to silence it.
Terms
7- standard input
- The input stream on file descriptor 0; its source may be a terminal, file, or pipe. Also appears in: wc, /proc: processes and the kernel as files
- standard output
- The main output stream on file descriptor 1; it can be redirected. Also appears in: cat, strace
- standard error
- The diagnostic stream on file descriptor 2, separate from standard output. Also appears in: Exit codes: $?, && and ||, sysctl, Bash scripts: running, variables, arguments, strace
- file descriptor
- A non-negative integer a process uses to refer to an open file, pipe, or socket. By convention, 0, 1, and 2 are the standard streams; a process's open descriptors are listed in /proc/<PID>/fd. Also appears in: flock, Log rotation with logrotate, lsof, strace and 1 more
- pipeline
- A chain of commands joined by |: each command's standard output feeds the next command's standard input, and the commands run concurrently. The pipeline's exit status is that of the last command unless pipefail is set. Also appears in: Exit codes: $?, && and ||, sed and awk, sort, watch and 13 more
- /dev/null
- A special device file: it accepts any output and keeps nothing, and reading from it gives end of file at once. 2> /dev/null throws error messages away. Also appears in: /proc: processes and the kernel as files, AppArmor, find, HTTP and 4 more
See also
- bash — the shell that performs redirections.
- tee — split a stream: to the screen and a file,
sudoincluded. - cat — join files and write short text with
<<EOF. - grep — the main filter in pipelines.
- sort, uniq, cut, wc — the filters pipelines are built from.
- text-tools — tr, paste, column, comm and other pipeline stages.
- xargs — turn output into arguments for the next command.
- bash-scripting —
set -o pipefailand exit codes in scripts.
Found an inaccuracy? Report an error in the article