Understanding stdin, stdout, and stderr
What Are the Standard Streams?
Saving a log with > file, chaining commands with a | (pipe) — as you learn the command line, you keep running into these symbols. Behind them is a mechanism called the standard streams: stdin, stdout, and stderr.
This guide untangles what each of the three streams is, why output is split into two kinds, and how to switch where input and output go using redirection and pipes — all through a conversation between Lina and Linny-senpai.
What You'll Learn
- What stdin, stdout, and stderr are each responsible for
- Why output is split into two streams (stdout and stderr)
- The meaning of the numbers 0 / 1 / 2 (file descriptors)
- How to switch destinations with
>,2>, and&> - How to use the pipe
|and input redirection<
1. What Are the Standard Streams?
Conclusion: The standard streams are three default paths a command uses — one to take input, one to send normal results, and one to send errors. They are called stdin, stdout, and stderr.
- stdin (standard input): the entrance where data comes into the command
- stdout (standard output): the exit for normal results
- stderr (standard error): the exit for errors and warnings
What "standard" means
"Standard" means "the default path used unless you say otherwise." For example, the result of ls appears on screen because stdout's default destination is the screen (the terminal). Redirection and pipes are simply ways to change that destination afterward.
2. Why Is Output Split Into stdout and stderr?
Conclusion: To keep "results you want to pass on" separate from "errors you want a human to read." Splitting them lets you save just the results or grab just the errors.
- stdout = normal results (data you want to pass on or save)
- stderr = errors and warnings (messages meant for a human)
That way, even if you save the results to a file, the errors still show up on screen so you don't miss them.
A familiar analogy
On a factory line, stdout is the "conveyor belt carrying finished products," and stderr is the "alarm that signals a defect." You don't want the alarm sound inside the box of finished goods (the file). So they're kept separate.
3. What Are the Numbers 0 / 1 / 2?
Conclusion: stdin, stdout, and stderr are assigned the numbers 0 / 1 / 2 (file descriptors). The
2in2>refers to that number.
2> in an example — what is that 2?| Number | Name | Role |
|---|---|---|
| 0 | stdin | Standard input (entrance) |
| 1 | stdout | Standard output (normal exit) |
| 2 | stderr | Standard error (error exit) |
How numbers map to symbols
The redirection symbols connect directly to these numbers.
>is shorthand for1>(sends stdout)2>sends stderr<is shorthand for0<(reads stdin)
Once you remember "the 2 in 2> is stderr's number," the symbols suddenly make sense.
4. How Do I Change Where Output Goes?
Conclusion: Use
>to send stdout and2>to send stderr to a file. To combine both, use> file 2>&1or&> file.
ls /etc > filelist.txt
With >, the stdout content that would have appeared on screen is written to filelist.txt instead (nothing appears on screen). Note that > overwrites, while >> appends.
To save only the errors, use 2>.
ls /not-exist 2> errors.txt
(nothing appears on screen; errors.txt records the following) ls: cannot access '/not-exist': No such file or directory
> and stderr is 2>. What if I want both in one file?2>&1. It means "send stderr (2) to the same destination as stdout (1)."command > output.txt 2>&1
Order matters with 2>&1
2>&1 means "make stderr match stdout's current destination." So you must write > output.txt first. If you reverse the order, like command 2>&1 > output.txt, stderr stays pointed at its old destination (the screen). The newer &> file notation (bash) combines both without worrying about order.
command &> output.txt
5. How Do Pipes and Standard Input Work?
Conclusion: A pipe
|connects the left command's stdout to the right command's stdin.<feeds a file's contents in as stdin.
| connects the left command's stdout directly to the right command's stdin.ls /etc | grep conf
In this example, the output (stdout) of ls /etc flows straight into the input (stdin) of grep conf. grep then picks out only the lines that contain conf.
Picture the flow
ls /etc ──stdout──▶ | ──stdin──▶ grep conf ──stdout──▶ screen
A pipe is like a hose that connects "the previous command's exit" directly to "the next command's entrance."
To feed a file's contents in as stdin, use <.
sort < names.txt
This streams the contents of names.txt into the standard input of sort, which sorts and prints them. The result is the same as sort names.txt, but it makes the "connect a file to stdin" behavior of standard input easy to see.
To practice pipes and redirection more hands-on, see Pipes and Redirection Basics. When you want output to go to both the screen and a file, How to Use the tee Command is handy.
Summary
- The standard streams are three paths: stdin (input), stdout (normal output), and stderr (error output)
- There are two output streams to keep "results" and "errors" from mixing
- The three are assigned the numbers 0 / 1 / 2 (file descriptors)
- Use
>for stdout and2>for stderr to send them to a file (both with> file 2>&1or&> file) - A pipe
|connects stdout to the next stdin, and<feeds a file in as stdin