Home← Linux from ScratchCheat sheet
M9Linux from Scratch

M9 — Redirection, pipes, and quoting

Time: about 50–80 minutes
Lab root: /tmp/linux-lab-pushpjeet

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:

  1. Redirect standard output with > and >>
  2. Redirect standard error with 2> and merge streams with 2>&1
  3. Feed a command from a file with <
  4. Chain commands with pipes | and split a stream with tee
  5. 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#

  1. > when you meant >> — truncated log or config. Pause before overwrite redirects.
  2. Redirecting only stdout and wondering where the error went — use 2> or 2>&1.
  3. Wrong order: >file 2>&1 vs 2>&1 >file — learn one reliable pattern: cmd >file 2>&1.
  4. Unquoted spaces — cat my notes.txt looks for two files named my and notes.txt.
  5. 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
  1. Run date > now.txt and date >> now.txt. Confirm two lines with cat -n now.txt.
  2. Run ls /nope 2> err.txt and read err.txt.
  3. Run ls /tmp /nope 2>&1 | tee mixed.txt | wc -l.
  4. Create "weekly report.txt" with a one-line message using quotes.
  5. 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 ls as 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#

  1. Save errors only: make 2> build.err
  2. Save everything: make > build.log 2>&1
  3. Uppercase and save: echo hi | tr a-z A-Z | tee hi.txt
  4. Quoted file: cat "my notes.txt"
Answer key
  1. 2>
  2. > build.log 2>&1 (order as shown)
  3. | tee hi.txt
  4. quotes around my notes.txt

Order the steps#

Build a pipeline that lists a directory, saves the full stream (including errors), and counts lines:

  1. Append | wc -l
  2. Run ls /tmp /missing
  3. Add 2>&1
  4. 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

  1. Create three empty files with touch a.txt b.txt c.txt.
  2. Run a command that lists them and also tries a missing path; merge streams; tee to run.log.
  3. grep -i cannot run.log to show the error line.
  4. Create a file named team notes.txt (with a space) and cat it 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.

Continue

← Linux from Scratch hub · Cheat sheet · All tutorials

Newsletter

Liked this? Get the next tutorial by email

New tutorials, labs and cheat sheets, plus AWS batch dates and Oracle tips if you want them. No spam, unsubscribe anytime.

I’m interested in

Double opt-in: you’ll get a confirmation email first. Privacy policy

WhatsApp