Linux Streams: Standard Input, Output, and Error
Learn how Linux stdin, stdout, and stderr work, including file descriptors, redirection, pipelines, /dev/null, and troubleshooting mixed output.
Linux commands communicate through streams: ordered flows of data entering or leaving a running program. A command runs as a process. It can read data from an input stream and write data to one or more output streams.
An input stream supplies data to a program. Output streams carry data away from it. The keyboard and terminal are common defaults, but they are not the only possible sources or destinations. A file, another command, or a special device can also provide or receive stream data.
The Three Standard Streams
Command-line programs conventionally start with three standard streams:
| Stream | Abbreviation | File descriptor | Typical default source or destination | Primary use |
|---|---|---|---|---|
| Standard input | stdin | 0 | Keyboard or terminal | Data read by a command |
| Standard output | stdout | 1 | Terminal display | Normal command results |
| Standard error | stderr | 2 | Terminal display | Diagnostics and error messages |
A file descriptor is a small integer that a process uses as a handle for an open input/output resource. The shell and the process use descriptors 0, 1, and 2 to refer to stdin, stdout, and stderr.
Default Stream Connections
In a typical interactive terminal, the flow looks like this:
keyboard or terminal input ──> stdin (0) ──> command/process ──> stdout (1) ──> terminal
└──> stderr (2) ──> terminalBoth stdout and stderr normally appear on the same terminal, but they remain separate streams. The shell establishes these connections before launching a command, and shell syntax can change them.
Keeping stdout and stderr separate is useful when normal results must be saved, processed, or piped while diagnostics remain visible or go to a different file.
Standard Input
Standard input, or stdin, is the normal data source read by a command. During an interactive session, it usually receives characters typed at the keyboard.
Some commands read stdin when no input file is named. For example, cat copies stdin to stdout:
catType one or more lines. Each line is copied to the terminal. On many terminals, press Ctrl+D to indicate end-of-input.
Stdin can also come from a file, a here-document, a here-string, or another command.
Input Redirection from a File
The < operator makes a file become stdin:
sort < names.txtThe shell opens names.txt and supplies it to sort. The command behaves as though the data arrived through standard input rather than from the keyboard.
Other Input Sources
A pipeline supplies stdin from another command:
printf '%s\n' banana apple cherry | sortA here-document provides a block of text as stdin:
cat <<EOF
First line
Second line
EOFA here-string provides one string as stdin:
wc -w <<< 'Linux streams are useful'Standard Output
Standard output, or stdout, is the normal channel for a command's results. Unless redirected, stdout is displayed in the terminal.
echo "Hello, Linux"This command writes its normal result to stdout, so the terminal displays it.
Writing stdout to a File
The > operator redirects stdout to a file and replaces that file's existing contents:
ls > files.txtTo append stdout to the end of a file instead, use >>:
date >> activity.logYou can explicitly identify stdout with file descriptor 1:
ls 1> files.txtFor ordinary output, > and 1> have the same effect.
Standard Error
Standard error, or stderr, is intended for diagnostics, warnings, and error messages. It uses file descriptor 2.
For example, this command may produce normal results for /etc and an error for /missing:
find /etc /missingThe normal results go to stdout, while the diagnostic goes to stderr. Both commonly appear on the terminal, which can make them look like one output stream even though they are separate.
Redirecting stderr
Use 2> to write stderr to a file, replacing that file's contents. Use 2>> to append diagnostics:
find /etc /missing 2> errors.txt
command 2>> errors.logTo keep normal output and errors separate, redirect each descriptor independently:
find /etc /missing > results.txt 2> errors.txtHere, successful results go to results.txt, while diagnostics go to errors.txt.
Combining stdout and stderr
The operator 2>&1 sends stderr to the current destination of stdout. A common form is:
command > all.txt 2>&1The order matters. First, > all.txt sends stdout to all.txt. Then 2>&1 sends stderr to the same destination. This is the reliable form for putting both streams in one file.
Redirection is evaluated from left to right. For example:
command 2>&1 > all.txtIn this order, stderr first copies the original stdout destination, usually the terminal. The later stdout redirection does not change stderr's already-established destination, so the two streams may not both enter all.txt.
Discarding Output with /dev/null
/dev/null is a special device that accepts written data and discards it. Use it when a particular stream is intentionally unneeded:
find /etc /missing 2> /dev/nullThis suppresses diagnostics while leaving normal stdout visible. To discard normal output, use > /dev/null. To discard both streams, use:
command > /dev/null 2>&1Redirection Fundamentals
| Syntax | Effect | Example |
|---|---|---|
< file | Use a file as stdin | sort < names.txt |
> file | Write stdout to a file, replacing its contents | ls > files.txt |
>> file | Append stdout to a file | date >> activity.log |
2> file | Write stderr to a file, replacing its contents | command 2> errors.txt |
2>> file | Append stderr to a file | command 2>> errors.log |
2>&1 | Send stderr to the current stdout destination | command > all.txt 2>&1 |
| | Send stdout to the next command's stdin | command | less |
Pipelines
A pipeline connects commands. The pipe operator | sends the first command's stdout to the second command's stdin.
ls -1 | wc -lHere, ls -1 writes one entry per line to stdout. The pipe supplies that data as stdin to wc -l, which counts the lines.
Pipelines are useful for filtering, searching, counting, and transforming output:
printf '%s\n' apple banana apricot | grep '^ap' | wc -lA basic pipe transfers stdout only. Stderr remains connected to its existing destination, usually the terminal. Therefore, this does not normally send error messages to grep:
find /etc /missing | grep deniedTo include stderr, merge it into stdout before the pipe:
find /etc /missing 2>&1 | grep -i "denied"Reading Mixed Output
Normal results and diagnostics can appear interleaved on a terminal because both streams share the same visible destination. Their order may also seem unexpected because programs can buffer stdout and stderr differently or write to them at different times.
When investigating a command, capture the streams separately:
find /etc /missing > results.txt 2> errors.txtThen inspect each file independently:
less results.txt
less errors.txtWhen scripting, do not assume every command uses stdout and stderr in exactly the same way. Consult the command's documentation when deciding which stream should be captured, displayed, or piped.
Troubleshooting Stream Problems
Errors Still Appear on the Screen
If you run command > output.txt and errors still appear, only stdout was redirected. Stderr is still connected to the terminal. Use command 2> errors.txt or combine both streams with command > output.txt 2>&1.
A Pipeline Does Not Process Errors
A normal pipe transfers stdout only. If grep or wc does not receive error messages, merge stderr before the pipe:
command 2>&1 | grep patternEarlier File Contents Disappeared
The > operator overwrites a destination file. Use >> when new output should be appended instead.
A Command Waits for Input
A command may appear to pause because it is reading stdin. Type the required input, redirect a file with <, pipe data into it, or send end-of-input when appropriate.
Combined Output Has Unexpected Ordering
Even after combining streams, output order can be affected by buffering and by the times at which the program writes each stream. Capture stdout and stderr separately when precise diagnosis or ordering matters.
Quick Reference
- stdin (0): data read by a command.
- stdout (1): normal command results.
- stderr (2): diagnostics, warnings, and errors.
- Redirection: shell syntax that changes a stream's source or destination.
- Pipeline: a connection from one command's stdout to another command's stdin.
- <: read stdin from a file.
- >: overwrite a file with stdout.
- >>: append stdout to a file.
- 2>: overwrite a file with stderr.
- 2>&1: send stderr to stdout's current destination.
- /dev/null: discard written data.
For related fundamentals, see Bourne Again Shell Bash, Search For Text Strings Using Grep, File Structure In Linux, and Linux command-line topics.