LinuxII · Shell and Command-Line OperationsPipelines and redirection
Redirection, pipes, and three-channel I/O
What you'll learn
- Redirect stdin, stdout, and stderr to and from files
- Build pipelines with `|` and process substitution
- Use /dev/null, here-documents, and here-strings correctly
- Distinguish destructive overwriting from appending redirection
Prerequisites
Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09
Redirection and pipes are what turn a collection of small commands into a production-grade text-processing toolkit. Most senior sysadmins can read a pipeline the way other engineers read code.
File descriptors
Every process starts with three open file descriptors inherited from its parent:
| Number | Name | Default | Convention |
|---|---|---|---|
| 0 | stdin | terminal keyboard | Input |
| 1 | stdout | terminal display | Normal output |
| 2 | stderr | terminal display | Diagnostics |
You can redirect any of them with the shell’s redirection operators.
Redirecting to files
$ echo hello > out.txt; cat out.txthello$ echo again >> out.txt; cat out.txthello
again$ ls /nonexistent 2> err.txt; cat err.txtls: cannot access '/nonexistent': No such file or directoryIllustrative output
$ ls /etc/passwd /nonexistent > out.txt 2> err.txt; cat out.txt; echo ---; cat err.txt/etc/passwd
---
ls: cannot access /nonexistent: No such file or directoryIllustrative output
Pipelines
A pipeline chains commands by feeding each command’s stdout into the next command’s stdin.
$ ps -eo pid,comm | head -10 PID COMM
1 systemd
124 systemd-journald
135 systemd-udevd
...Illustrative output
Pipelines have one important subtlety for production scripts: the
exit status of a pipeline is the exit status of the last
command, not the first. If cmd1 | cmd2 succeeds at cmd1 but
cmd2 fails, the pipeline as a whole reports cmd2’s failure —
which is what you want.
But if any earlier command in the pipeline fails, the failure is
silently lost unless you enable pipefail (covered in the
scripting lesson):
$ false | true; echo "pipeline exit: $?"; set -o pipefail; false | true; echo "with pipefail: $?"pipeline exit: 0
with pipefail: 1Illustrative output
/dev/null and the black hole
/dev/null is a device file that accepts any input and produces no
output. Two common uses:
$ command > /dev/null 2>&1$ command < /dev/nullHere-documents and here-strings
A here-document lets you embed a block of text as stdin to a command:
$ cat <<'EOF' > config.txt
setting_one=alpha
setting_two=beta with spaces
EOF
cat config.txtsetting_one=alpha
setting_two=beta with spacesIllustrative output
A here-string is the one-line version:
$ bc <<< "2 + 2"4Illustrative output
tee — the fork in the pipeline
tee reads stdin and writes it to both stdout and one or more files.
This is the canonical way to capture intermediate pipeline state
without breaking the chain:
$ journalctl -u ssh --since "1 hour ago" | tee /tmp/ssh.log | grep -i 'failed' | head -20...Illustrative output
WhyThisMatters
Knowledge check
Knowledge check · 3 questions
Q1. In `command > out.txt 2>&1`, which streams end up in out.txt?
Q2. A pipeline `cmd1 | cmd2` exits with the status of cmd1 by default.
Q3. Which of the following are safe patterns in production shell scripts? Select all that apply.
Passing score: 75%. Answers are checked in this browser.