← Back to course

Pipes, Redirects, and Command Chaining

Pipes, Redirects, and Command Chaining

Welcome back.

In the previous lesson, you wrote your first Bash script.

Now we learn one of the most powerful ideas in the Linux terminal:

Combining commands.

Small commands are useful.

Combined commands are powerful.

This is where the terminal stops being a list of separate tools and becomes a workshop.

A slightly chaotic workshop.

But still a workshop.

What You’ll Learn

In this lesson, you’ll learn how to:

The Mission

Your mission is simple:

Learn how to make commands work together.

Because one command is useful.

Three commands connected together can make you look like you secretly work at NASA.

With a laptop.

And questionable sleep.

What Is a Pipe?

A pipe sends the output of one command into another command.

The pipe symbol is:

|

Example:

ls | wc -l

This means:

List files, then count the lines.

ls produces output.

wc -l counts lines.

The pipe connects them.

Very elegant.

Very Linux.

Count Files in a Folder

Try:

ls

Now try:

ls | wc -l

You will see a number.

That number is how many lines ls printed.

Not always perfect for complex cases, but useful for learning.

The terminal is now passing information like a waiter carrying plates between commands.

Hopefully not dropping them.

Search Command Output

You can pipe output into grep.

Try:

ls | grep ".txt"

This lists only entries that contain .txt.

You can also search processes:

ps aux | grep node

This means:

Show all processes, then keep only lines containing node.

This is extremely useful when debugging development servers.

Especially when Node.js refuses to leave like a guest after midnight.

Sort Output

Create a small file:

echo "banana" > fruits.txt
echo "apple" >> fruits.txt
echo "orange" >> fruits.txt
echo "apple" >> fruits.txt

Show it:

cat fruits.txt

Now sort it:

cat fruits.txt | sort

You should see the lines in alphabetical order.

Remove Duplicates

To remove duplicate neighboring lines, use uniq.

Better with sort first:

cat fruits.txt | sort | uniq

This means:

Print the file, sort the lines, remove duplicates.

Small commands.

Powerful result.

Like building a sandwich, but with text.

Count Unique Values

You can add wc -l:

cat fruits.txt | sort | uniq | wc -l

This counts how many unique fruits you have.

The command looks longer now.

But it is readable when you understand the flow:

cat -> sort -> uniq -> count

That is the magic of pipes.

Redirect Output to a File

The > symbol saves output into a file.

Try:

echo "Hello, file!" > output.txt

Now read it:

cat output.txt

You should see:

Hello, file!

Important: > overwrites the file.

If the file already had content, it is replaced.

Linux does not say:

“Are you sure?”

Linux says:

“Done.”

Cold. Efficient. Slightly scary.

Append Output to a File

The >> symbol appends output.

Try:

echo "First line" > notes.txt
echo "Second line" >> notes.txt
echo "Third line" >> notes.txt
cat notes.txt

You should see:

First line
Second line
Third line

Use:

>

to replace.

Use:

>>

to add.

This difference matters.

A lot.

Redirect Errors

There are two common output streams:

stdout = normal output
stderr = error output

Normal output can be redirected with:

>

Errors can be redirected with:

2>

Try:

ls missing-folder 2> error.log

Now read the error file:

cat error.log

You should see the error message saved there.

This is useful when scripts produce errors and you want to capture them.

Because sometimes errors are not disasters.

They are evidence.

Redirect Output and Errors Together

To save both normal output and errors:

command > output.log 2>&1

Example:

ls ~/terminal-practice missing-folder > result.log 2>&1

Then:

cat result.log

This saves both successful output and errors in the same file.

Very useful for logs.

Very boring.

Very professional.

Use tee

tee lets you see output and save it at the same time.

Try:

echo "Terminal power" | tee message.txt

You will see the text on screen, and it will also be saved into message.txt.

To append with tee, use:

echo "Another line" | tee -a message.txt

tee is useful when you want visibility and logging at the same time.

Like saying:

“I want to see what happens, but I also want receipts.”

Chain Commands with ;

The ; symbol runs commands one after another.

echo "One"; echo "Two"; echo "Three"

Even if one command fails, the next one still runs.

Example:

mkdir demo; cd demo; pwd

This is simple command chaining.

Useful.

But not always safe.

Chain Commands with &&

The && symbol runs the next command only if the previous command succeeds.

Example:

mkdir safe-demo && cd safe-demo && pwd

This means:

Create folder. If that works, enter it. If that works, show location.

This is safer than ;.

If something fails, the chain stops.

Very useful for scripts and setup commands.

Less drama.

More control.

Chain Commands with ||

The || symbol runs the next command only if the previous command fails.

Example:

mkdir safe-demo || echo "Folder already exists or could not be created."

Another example:

ping -c 1 example.com || echo "Network problem."

This is useful for fallback messages.

The terminal says:

“If this fails, do that.”

Very practical.

Very adult.

Combine Everything

Here is a small workflow:

ps aux | grep node > node-processes.txt
cat node-processes.txt

This finds Node.js processes and saves them into a file.

Another example:

ls -la | tee files.log | grep ".txt"

This means:

List files with details, save the full output to files.log, and also show only .txt lines.

Now we are cooking.

Terminal cooking.

No pan.

Only pipes.

Common Mistakes

Overwriting a file by accident

This overwrites:

echo "new text" > notes.txt

This appends:

echo "new text" >> notes.txt

Before using >, think.

Your files deserve at least one second of respect.

Forgetting that pipes pass output, not files

This works:

cat fruits.txt | sort

But many commands can read files directly:

sort fruits.txt

Pipes are powerful, but do not use them just to look cool.

The terminal knows when you are pretending.

Using grep and matching itself

When you run:

ps aux | grep node

you may also see the grep node command itself.

That is normal.

You can avoid it with:

ps aux | grep "[n]ode"

A little trick.

Linux people love little tricks.

Sometimes too much.

Practice

Try this:

cd ~/terminal-practice
echo "banana" > fruits.txt
echo "apple" >> fruits.txt
echo "orange" >> fruits.txt
echo "apple" >> fruits.txt
cat fruits.txt
cat fruits.txt | sort
cat fruits.txt | sort | uniq
cat fruits.txt | sort | uniq | wc -l
echo "Saved output" > saved.txt
echo "Appended output" >> saved.txt
cat saved.txt
ls missing-folder 2> error.log
cat error.log

Then answer:

  1. What does | do?
  2. What does > do?
  3. What does >> do?
  4. What does 2> do?
  5. What does && do?
  6. What does || do?

Mini Challenge

Create a file called animals.txt with these lines:

cat
dog
bird
cat
dog
elephant

Then use commands to:

  1. Sort the file.
  2. Remove duplicates.
  3. Count unique animals.
  4. Save the sorted unique list into unique-animals.txt.
  5. Show the result on screen and save it at the same time with tee.

No mouse.

The mouse has completed the course as an observer.

Summary

Today you learned:

This is one of the deepest ideas in the Linux terminal.

Do one thing well.

Then connect those things.

That is the Unix philosophy in action.

Course Complete

Congratulations.

You have completed the Linux Terminal Course.

You started with the mysterious black window.

Now you can:

The terminal is no longer a monster.

It is a tool.

A sharp tool.

A powerful tool.

A tool that still deserves respect.

Now go practice.

Carefully.

And maybe back up your files first.