# Three Streams: Output, Errors and Input

Every command has three streams, output, errors and input, and redirection sends each where you choose, with 2> for errors, &> or > file 2>&1 for both together, /dev/null to throw them away and &lt; to read a file in.

Apprentice · Unix · Linux · Updated November 10, 2026

## After this lesson you can

- Send a command's errors to a file with 2>, or output and errors together with &> or > file 2>&1
- Throw away output you don't need with /dev/null, and feed a file to a command with &lt;

## Key takeaways

- A command prints results on standard output (stdout) and problems on standard error (stderr). Both reach the screen, but they're separate streams.
- > and | carry standard output only, so errors still reach the screen. 2> (read "two into") sends the errors into a file.
- &> file, or > file 2>&1, sends output and errors into the same file. The 2>&1 goes after the >.
- /dev/null throws away whatever is sent to it, so 2> /dev/null hides errors you expected.
- < (read "from") feeds a file to a command's standard input (stdin), the stream a pipe also feeds.

Every evening, Bea wants the day's files counted, with the counts saved in one file and anything that went wrong saved in another, so she can read the problems first. A log of what worked and a log of what failed: that's how a nightly backup, a website's server and every scheduled job keep their records. Her first try goes wrong in a puzzling way, though. She sends the output into a file with `>`, and an error still lands on her screen. The reason is that a command has more than one way out, and once you know them, you choose where each one goes.

The examples use the bakery folder from *Pipes: |*. If you don't have it yet, the setup lines in that lesson make it. Then go into it with `cd ~/terminal-practice/bakery`.

## Output and errors: two streams

Ask `wc -l` to count the lines of `orders.csv` and `refunds.csv`. Bea thought she had exported her refunds too, but she hadn't:

```bash
wc -l orders.csv refunds.csv
```

```text
  521 orders.csv
wc: refunds.csv: No such file or directory
  521 total
```

Two kinds of line came out: counts and a complaint. They look alike on the screen, but they travel separately. A command has two ways out, like a shop with a front door for customers and a back door for the trash: **standard output** (stdout, read "standard out") carries the results, and **standard error** (stderr) carries the problems. Both lead to your screen unless you say otherwise. (The exact wording of error messages differs a little on a Mac and from one Linux to another; the meaning is the same.)

Watch what `>` does with them:

```bash
wc -l orders.csv refunds.csv > counts.txt
cat counts.txt
```

```text
wc: refunds.csv: No such file or directory
  521 orders.csv
  521 total
```

The error reached the screen at once, and `counts.txt` holds only the counts. `>` carries standard output only, and so does a pipe.

## 2> sends errors to a file

Each stream has a number: standard input is 0, standard output is 1 and standard error is 2. `>` is short for `1>`. To send the errors somewhere, put a 2 in front of the arrow: `2>` (read "two into"):

```bash
wc -l orders.csv refunds.csv > counts.txt 2> errors.txt
cat errors.txt
```

```text
wc: refunds.csv: No such file or directory
```

Nothing reached the screen this time. The counts went into `counts.txt` and the complaint into `errors.txt`: one log of what worked and one of what failed. Like `>`, `2>` replaces the file each time; `2>>` adds to its end, like `>>`.

## Both in one file: &> and 2>&1

Sometimes you want everything in one file, in the order it happened. `&>` (read "both into") sends both streams there:

```bash
wc -l orders.csv refunds.csv &> everything.txt
cat everything.txt
```

```text
  521 orders.csv
wc: refunds.csv: No such file or directory
  521 total
```

You'll also see an older way, in tutorials and in scripts for other shells: `> everything.txt 2>&1`. Read `2>&1` as "errors go where output goes":

```bash
wc -l orders.csv refunds.csv > everything.txt 2>&1
cat everything.txt
```

```text
  521 orders.csv
wc: refunds.csv: No such file or directory
  521 total
```

The order matters. The shell sets up the arrows from left to right, so `2>&1` must come after `>`. Written the other way round, it sends errors to where output was going at that moment, the screen:

```bash
wc -l orders.csv refunds.csv 2>&1 > everything.txt
```

```text
wc: refunds.csv: No such file or directory
```

## /dev/null: the bin

Some errors are expected, and they bury the answer. Which file says which version of Linux this is? `find` (from *Finding Files: find*) can search `/etc`, the folder of system settings, but it complains about every folder in there you aren't allowed to read:

```bash
find /etc -name os-release
```

```text
find: ‘/etc/credstore’: Permission denied
find: ‘/etc/polkit-1/rules.d’: Permission denied
/etc/os-release
find: ‘/etc/ssl/private’: Permission denied
find: ‘/etc/credstore.encrypted’: Permission denied
```

`/dev/null` (read "dev null", or "the bin") is a special file that throws away everything sent into it. Send the complaints there:

```bash
find /etc -name os-release 2> /dev/null
```

```text
/etc/os-release
```

One clean answer. (The folders you're refused depend on the computer, so your list of complaints will differ.) Bin only the errors you expected: an error you didn't expect is the one you need to read.

## &lt; feeds a file in

The third stream, **standard input** (stdin), is where a command reads when it isn't given a file name. A pipe joins one command's output to the next command's input; `<` (read "from") joins a file to it instead:

```bash
wc -l < orders.csv
```

```text
521
```

Given a file name, `wc` prints the name after the count. Fed through `<`, it sees only the lines, so it prints only the number, which is handy when the number is all you want. A few commands, such as `tr` in *Columns and Characters: cut and tr*, read only standard input, so for them `<` or a pipe is the only way in.

![A command drawn as a box labeled wc, with three pipes: standard input (0) coming in on the left from orders.csv through <, standard output (1) leaving on the right into counts.txt through >, and standard error (2) leaving at the bottom into errors.txt through 2>](https://fsdtrainingmedia.blob.core.windows.net/public/images/2026/11/c0e2385e76594398a570473c92bff7d7.webp)

## Check yourself

2 questions to try on the lesson page.

## So what

Results and errors are separate streams, and you choose where each one goes. Every script that runs while you sleep relies on it: answers in one file, problems in another, and nothing lost.

## Key terms

- [Standard Streams](https://www.ask-codey.com/glossary/standard-streams)
- [Redirection](https://www.ask-codey.com/glossary/redirection)
- [/dev/null](https://www.ask-codey.com/glossary/dev-null)

## Cheat sheets

- [Three Streams: Output, Errors and Input](https://www.ask-codey.com/cheat-sheets/bash-streams-and-redirection-cheat-sheet)

## Related

- [Pipes: |](https://www.ask-codey.com/lessons/bash-pipes)
- [Writing to Files: echo, > and >>](https://www.ask-codey.com/lessons/bash-writing-to-files)

Source: https://www.ask-codey.com/lessons/bash-streams-and-redirection
