Redirection & Pipes
stdout, stderr, stdin — rewiring program I/O and building data pipelines
Quick check before you start: Do you know what
>does vs>>? If not, read on. If you can explain both and name the three standard streams, skip to Pipes.Practice this topic: Redirection & Pipes skill drill
After this lesson, you will be able to:
- Name the three standard streams (stdin, stdout, stderr) and their file descriptors
- Redirect output to files with
>and>> - Redirect input from files with
< - Redirect error output with
2> - Chain commands together with pipes (
|)
The Three Standard Streams
Every running program gets three I/O channels automatically:
| Stream | File Descriptor | Default | Purpose |
|---|---|---|---|
| stdin | 0 | keyboard | Input |
| stdout | 1 | terminal | Normal output |
| stderr | 2 | terminal | Error messages |
By default, both stdout and stderr print to your terminal. The shell lets you rewire these streams — sending output to files or feeding files as input.
Output Redirection
Overwrite with >
The > operator sends stdout to a file instead of the screen. If the file exists, it gets overwritten:
ls /usr/bin > programs.txt # save directory listing to a file
cat programs.txt # view the saved output
Append with >>
The >> operator adds to the end of a file without erasing it:
echo "first line" > log.txt # creates log.txt with one line
echo "second line" >> log.txt # adds a second line
cat log.txt
# first line
# second line
Redirect Errors with 2>
Stderr has file descriptor 2. To redirect only errors:
ls /nonexistent 2> errors.txt # error goes to file, not screen
cat errors.txt
# ls: cannot access '/nonexistent': No such file or directory
To redirect stdout and stderr to the same file:
gcc buggy.c > output.txt 2>&1 # both normal output and errors go to output.txt
The 2>&1 means “send file descriptor 2 (stderr) to wherever file descriptor 1 (stdout) is going.”
Input Redirection
The < operator feeds a file into a command’s stdin:
wc -l < /etc/passwd # count lines in passwd without passing filename
sort < names.txt # sort lines from a file
Without <, many commands accept a filename argument directly (sort names.txt). The difference: < makes the shell open the file and feed it to the command. Without <, the command opens the file itself. The result is usually the same, but < matters when a command only reads from stdin.
Pipes
The pipe operator | connects stdout of one command to stdin of the next. No temporary files needed:
ls /usr/bin | wc -l # count how many programs are in /usr/bin
Here ls writes its listing to stdout, and | feeds that directly into wc -l, which counts lines. The result is a single number.
Building Pipelines
Pipes chain together. Each command processes the output of the previous one:
cat /etc/passwd | cut -d: -f1 | sort | head -5
This pipeline:
cat /etc/passwd— reads the password filecut -d: -f1— extracts the first field (username) using:as delimitersort— sorts alphabeticallyhead -5— shows the first 5 lines
Another example — find the 10 largest files in a directory:
ls -lS /usr/bin | head -10
Pipes vs Redirection
| Operator | Connects | Example |
|---|---|---|
> |
command → file | ls > list.txt |
< |
file → command | sort < data.txt |
\| |
command → command | ls \| sort |
Redirection connects commands to files. Pipes connect commands to commands.
ls /usr/bin | wc -l output?ls prints one filename per line to stdout. The pipe sends that output to wc -l, which counts lines. The result is a single number: the count of entries in /usr/bin. The -l flag tells wc to count lines specifically, not words or characters.
What Comes Next
You can now redirect output, feed input from files, and chain commands into pipelines. Next, you will learn to search inside files with grep and regular expressions.