← 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