2.2 Input-Output Redirection and Pipes
Key Takeaways
- Every process has three standard streams: stdin (0), stdout (1), and stderr (2); redirection operators reconnect those streams to files or other commands.
- `>` truncates/overwrites; `>>` appends; `2>` redirects errors; `&>` or `>file 2>&1` merges stdout and stderr (order matters).
- Pipes `|` send stdout of the left command to stdin of the right; use `tee` when you need both a file and a pipeline continuation.
- Here-documents (`<<EOF`) and here-strings (`<<<`) feed multi-line or single-line stdin without temporary files—common in scripts and quick config writes.
- Never confuse `>` with `|`: redirecting to a filename overwrites that file; piping connects processes.
2.2 Input-Output Redirection and Pipes
Quick Answer: Use
>/>>for stdout to files,2>/2>>for stderr,<for stdin from a file, and|to connect commands. Merge streams withcommand >out 2>&1orcommand &>out. Append with>>when you must not destroy existing content.
The EX200 objective Use input-output redirection (>, >>, |, 2>, etc.) appears constantly: save command output as evidence, filter logs, create files non-interactively, and hide errors while capturing data. Redirection is pure bash syntax—the operators are processed by the shell, not by ls or grep themselves.
Standard Streams
| FD | Name | Default | Typical content |
|---|---|---|---|
| 0 | stdin | keyboard | Input you type or feed |
| 1 | stdout | terminal | Normal command output |
| 2 | stderr | terminal | Errors and diagnostics |
Programs write “normal” results to stdout and diagnostics to stderr so you can separate them. Example:
ls /etc/passwd /no/such/file
You see a successful listing and an error. They look mixed on the terminal, but they are different file descriptors—and can be redirected independently.
Redirecting Standard Output
command > file # overwrite/create file with stdout
command >> file # append stdout to file
command 1> file # explicit FD 1 (same as >)
Examples:
date > /tmp/timestamp.txt
uname -r >> /tmp/timestamp.txt
ls /etc > /tmp/etc-list.txt
Destructive trap: > truncates the target before the command runs. This classic mistake destroys data:
sort file.txt > file.txt # BAD: truncates file.txt first; result often empty
Safe patterns:
sort file.txt > file.sorted && mv file.sorted file.txt
sort -o file.txt file.txt # sort’s own in-place-safe output option
Redirecting Standard Error
command 2> errors.txt # overwrite error log
command 2>> errors.txt # append errors
command 2> /dev/null # discard errors
Practical exam use—find files while ignoring “Permission denied” noise:
find /etc -name '*.conf' 2>/dev/null
Capture only errors:
find /etc -name '*.conf' > /tmp/found.txt 2> /tmp/find-errors.txt
Merging stdout and stderr
You often want everything in one file for a lab report or grading artifact:
command > all.txt 2>&1
command &> all.txt # bash shorthand: both streams to all.txt
command &>> all.txt # append both streams
Order is critical:
command > all.txt 2>&1 # correct: point stdout to file, then send stderr where stdout goes
command 2>&1 > all.txt # WRONG intent: stderr follows old stdout (terminal), then stdout goes to file
Memorize the working form: >file 2>&1 or &>file.
Discard everything:
command > /dev/null 2>&1
command &>/dev/null
Redirecting Standard Input
command < input.txt
Examples:
wc -l < /etc/passwd
tr 'a-z' 'A-Z' < message.txt
mail -s "Report" admin@example.com < body.txt
Many commands also accept filenames as arguments (wc -l /etc/passwd). Using < forces stdin mode—useful for programs that only read stdin or when building pipelines from files.
Here-Documents and Here-Strings
Here-document feeds multi-line stdin until a delimiter:
cat > /tmp/motd <<'EOF'
Welcome to the exam lab system.
Unauthorized access is prohibited.
EOF
<<EOFallows parameter expansion inside the body.<<'EOF'(quoted delimiter) treats the body literally—prefer this when pasting configs with$characters.
Here-string feeds a single string:
grep -i error <<<"ERROR: disk full"
bc <<<"2+2"
These avoid temporary files and are faster for small content during the exam.
Pipes
A pipe connects stdout of the left command to stdin of the right:
command1 | command2 | command3
Examples:
ps aux | head -n 5
journalctl -u sshd | grep -i fail | tail -n 20
cut -d: -f1 /etc/passwd | sort | uniq
rpm -qa | grep httpd
Notes:
- By default, stderr does not go through the pipe—only stdout. To pipe errors too:
command 2>&1 | less
command |& less # bash: pipe stdout and stderr
- Each stage runs concurrently; the kernel buffers the stream.
- Exit status of a pipeline is the status of the last command unless
set -o pipefailis enabled (important in scripts; optional at interactive prompt).
tee: Save and Continue
tee writes stdin to a file and passes it to stdout:
dnf list installed | tee /tmp/packages.txt | grep kernel
Append with tee -a:
date | tee -a /var/tmp/run.log
Use tee when graders (or you) need a saved artifact and you still want to filter on screen.
Combining Operators in Real Tasks
Task pattern: inventory with clean logs
rpm -qa --qf '%{NAME}\n' 2>/dev/null | sort > /root/pkg-names.txt
Task pattern: run a command, keep full transcript
bash -x /usr/local/bin/setup.sh &> /root/setup-trace.log
Task pattern: create a config non-interactively
cat > /etc/issue <<'EOF'
RHEL 10 Lab — authorized use only
EOF
Task pattern: filter a large log for later review
grep -i error /var/log/messages 2>/dev/null | tee /root/errors.txt | wc -l
noclobber and Forced Overwrite
If set -o noclobber is active, > will not overwrite existing files:
set -o noclobber
echo hi > existing.txt # fails if exists
echo hi >| existing.txt # force overwrite despite noclobber
Default interactive shells on RHEL usually do not enable noclobber, but knowing >| avoids panic if a task environment sets it.
Process Substitution (Awareness)
Bash process substitution is useful though less central than basic pipes:
diff <(rpm -qa | sort) <(cat /root/baseline-pkg.txt | sort)
This feeds command output where a filename is expected. Prefer ordinary pipes for EX200 unless a comparison task needs two live streams.
Operator Quick Reference
| Operator | Meaning |
|---|---|
> | Redirect stdout, overwrite |
>> | Redirect stdout, append |
2> | Redirect stderr, overwrite |
2>> | Redirect stderr, append |
2>&1 | Send stderr to wherever stdout currently goes |
&> / &>> | Redirect both streams (overwrite / append) |
< | Take stdin from file |
<<DELIM | Here-document until DELIM |
<<< string | Here-string |
| ` | ` |
| ` | &` |
tee file | Duplicate stdin to file and stdout |
/dev/null | Discard data written to it |
Exam Traps Specific to Redirection
- Overwriting the source with
command file > file. - Wrong merge order
2>&1 >filevs>file 2>&1. - Forgetting root permissions when redirecting as a user:
sudo ls > /root/out.txtstill opens/root/out.txtas the user shell. Fix:
sudo ls | sudo tee /root/out.txt >/dev/null
sudo bash -c 'ls > /root/out.txt'
- Piping when you meant to save—
cmd | filetries to runfileas a command. - Assuming stderr is in the pipe—add
2>&1when searching error text that programs write to stderr.
RHEL 10 Practice Drill
Run this sequence in a lab and verify each file’s contents with cat and ls -l:
mkdir -p /tmp/io-lab && cd /tmp/io-lab
echo first > a.txt
echo second >> a.txt
ls /etc/passwd /nope > out.txt 2> err.txt
ls /etc/passwd /nope > both.txt 2>&1
cat a.txt out.txt err.txt both.txt
printf 'alpha\nbeta\ngamma\n' | tee lines.txt | grep e
wc -l < lines.txt
You should see appended lines in a.txt, only success in out.txt, only failure in err.txt, and both outcomes in both.txt.
Why This Matters for Later Objectives
Storage reports, journalctl filters, package queries, network dumps, and script debugging all depend on redirection fluency. If you still hunt for GUI “Save output” buttons, you will lose minutes on every multi-step graded item. Make operators muscle memory so cognitive load stays on the Linux problem, not on shell syntax.
Which command saves both normal output and error messages from find /etc -name '*.conf' into /tmp/find.out, overwriting any existing file?
Why is sort report.txt > report.txt dangerous?
You run sudo cat /etc/shadow > /root/shadow.copy as user student and get “Permission denied” related to the output file. What is the most accurate explanation?
Which pipeline both displays matching lines on the terminal and saves the full dmesg stream for later inspection?