Prerequisites#
- M3–M5 (files and paths) and M8 (expansions help you read examples)
- Comfort running simple commands and reading their on-screen output
Learning objectives#
By the end of this module you will be able to:
- Redirect standard output with
>and>> - Redirect standard error with
2>and merge streams with2>&1 - Feed a command from a file with
< - Chain commands with pipes
|and split a stream withtee - Choose single quotes, double quotes, or backslash escapes so the shell does what you mean
Three streams every process has#
| Stream | Number | Usual meaning |
|---|---|---|
| stdin | 0 | Input (keyboard by default) |
| stdout | 1 | Normal output (screen) |
| stderr | 2 | Errors and diagnostics (screen) |
Redirection and pipes reconnect those streams to files or other programs.
mkdir -p /tmp/linux-lab-pushpjeet/redirect
cd /tmp/linux-lab-pushpjeet/redirect
Redirecting stdout: > and >>#
Overwrite a file with stdout:
ls /tmp/linux-lab-pushpjeet > listing.txt
cat listing.txt
Example output written to the file:
brace-demo
globs
redirect
vim-lab
(Your directory listing will reflect whatever you already created.)
Append instead of overwriting:
echo "append line" >> listing.txt
cat listing.txt
Danger: > truncates the target immediately. Mistyping > instead of >> can wipe a file you cared about. Prefer >> when you mean “add to the log”.
Redirecting stderr: 2>#
Errors use stream 2:
ls /no/such/path 2> errors.txt
cat errors.txt
Real output captured in errors.txt:
ls: cannot access '/no/such/path': No such file or directory
The terminal stays quiet because stderr went to the file.
Merging stderr into stdout: 2>&1#
Often you want both streams in one place (a log, or a pipe):
ls /tmp /no/such 2>&1 | head -5
Example:
ls: cannot access '/no/such': No such file or directory
/tmp:
...
Order matters. A common pattern to write everything to one file:
{ echo out; echo err >&2; } > both.txt 2>&1
cat both.txt
out
err
Read 2>&1 as “make stderr point at whatever stdout currently points at.”
stdin from a file: <#
printf 'alpha\nbeta\ngamma\n' > words.txt
wc -l < words.txt
Many commands also accept a filename argument (wc -l words.txt). The < form feeds stdin — useful for tools that only read stdin, or when you are building pipelines.
Pipes |#
A pipe connects stdout of the left command to stdin of the right:
printf 'lineA\nlineB\n' | tr 'a-z' 'A-Z'
LINEA
LINEB
Build filters step by step:
ls /tmp/linux-lab-pushpjeet | sort | head -n 5
Each stage does one job. That is the UNIX style you will use forever.
tee — see it and save it#
tee copies stdin to a file and passes it through to stdout:
printf 'lineA\nlineB\n' | tee captured.txt
cat captured.txt
lineA
lineB
(and the same lines are on the screen when you run the pipe). Append with tee -a.
Quoting: single, double, and backslash#
The shell treats spaces and special characters specially. Quotes protect them.
echo 'literal $HOME'
echo "expanded $HOME"
echo "escaped: \$HOME"
Real lab output:
literal $HOME
expanded /home/box
escaped: $HOME
| Quoting | Effect |
|---|---|
'…' |
Almost everything literal (no $ expansion, no globs) |
"…" |
Expand $VAR and $(…), but keep spaces together |
\ |
Escape the next character |
Filenames with spaces need quotes:
echo 'hello' > "my notes.txt"
cat "my notes.txt"
Without quotes, the shell splits on spaces and you get the wrong arguments.
Combining ideas#
Save a directory listing and its errors together, then search:
ls /tmp/linux-lab-pushpjeet /missing 2>&1 | tee ls-mixed.log | grep -i 'cannot\|vim' || true
You now have a log file and a filtered view.
Common mistakes#
>when you meant>>— truncated log or config. Pause before overwrite redirects.- Redirecting only stdout and wondering where the error went — use
2>or2>&1. - Wrong order:
>file 2>&1vs2>&1 >file— learn one reliable pattern:cmd >file 2>&1. - Unquoted spaces —
cat my notes.txtlooks for two files namedmyandnotes.txt. - Piping after a redirect that already emptied stdout — sketch the stream path on paper once; it clicks.
Hands-on lab#
mkdir -p /tmp/linux-lab-pushpjeet/m9-lab
cd /tmp/linux-lab-pushpjeet/m9-lab
- Run
date > now.txtanddate >> now.txt. Confirm two lines withcat -n now.txt. - Run
ls /nope 2> err.txtand readerr.txt. - Run
ls /tmp /nope 2>&1 | tee mixed.txt | wc -l. - Create
"weekly report.txt"with a one-line message using quotes. - Pipe
echo 'linux from scratch' | tr 'a-z' 'A-Z' | tee shout.txt.
Verify: now.txt has two timestamps; mixed.txt contains both listing and error text; shout.txt is uppercase.
Practice: check your understanding#
Multiple choice#
1. Which operator appends stdout to a file?
- A.
> - B.
>> - C.
2> - D.
|
Answer
B. >> appends. > overwrites.
2. What does 2>&1 do?
- A. Duplicate stdin
- B. Send stdout to stderr only
- C. Point stderr at the same place as stdout
- D. Open file descriptor 21
Answer
C. stderr is merged into whatever stdout currently targets.
3. In ls | grep vim, what does grep read?
- A. The keyboard only
- B. A file named
ls - C. The stdout of
lsas its stdin - D. stderr of
ls
Answer
C. The pipe connects stdout of ls to stdin of grep.
4. Which echo keeps $HOME as literal text?
- A.
echo "$HOME" - B.
echo '$HOME' - C.
echo $HOME - D.
echo $(HOME)
Answer
B. Single quotes prevent parameter expansion.
5. What is tee for?
- A. Terminating pipes
- B. Writing stdin to a file while still printing it
- C. Replacing
>always - D. Editing files in place like vim
Answer
B. tee saves a copy and continues the pipeline.
Match the columns#
| Operator | Effect | ||
|---|---|---|---|
| 1 | > |
A | Append stdout to file |
| 2 | >> |
B | Overwrite file with stdout |
| 3 | 2> |
C | Connect stdout → next stdin |
| 4 | 2>&1 |
D | Redirect stderr to a file |
| 5 | | |
E | Merge stderr into stdout |
| 6 | < |
F | Read stdin from a file |
Answer key
1→B, 2→A, 3→D, 4→E, 5→C, 6→F
Fill in the blank#
- Save errors only:
make 2> build.err - Save everything:
make > build.log 2>&1 - Uppercase and save:
echo hi | tr a-z A-Z | tee hi.txt - Quoted file:
cat "my notes.txt"
Answer key
2>> build.log 2>&1(order as shown)| tee hi.txt- quotes around
my notes.txt
Order the steps#
Build a pipeline that lists a directory, saves the full stream (including errors), and counts lines:
- Append
| wc -l - Run
ls /tmp /missing - Add
2>&1 - Add
| tee full.log
Answer key
2 → 3 → 4 → 1
ls /tmp /missing 2>&1 | tee full.log | wc -l
Mini terminal challenge#
Goal: Produce a small log with both success and failure lines.
Setup
mkdir -p /tmp/linux-lab-pushpjeet/m9-challenge
cd /tmp/linux-lab-pushpjeet/m9-challenge
Tasks
- Create three empty files with
touch a.txt b.txt c.txt. - Run a command that lists them and also tries a missing path; merge streams;
teetorun.log. grep -i cannot run.logto show the error line.- Create a file named
team notes.txt(with a space) andcatit using correct quoting.
Verify: run.log exists; grep finds the missing-path message; cat "team notes.txt" works.
Stretch: Append a second run to run.log with tee -a.
Next: M10 — Variables, history, and line editing — customise your shell session and reuse commands.