# The pipe: joining commands together

Course: Terminal Basics — https://zero2vibecode.com/learn/terminal-basics
Canonical URL: https://zero2vibecode.com/learn/terminal-basics/3-3-the-pipe

The `|` symbol feeds one command's output straight into the next one, so small tools combine into exactly the tool you needed.

Every command so far has printed to the screen. The pipe sends that output somewhere better: into another command.

## The vertical bar

```
cat server.log | grep ERROR
```

```
ERROR database timeout
ERROR disk full
```

Read it left to right:

1. `cat server.log` produces the file's text
2. `|` catches that text instead of letting it hit the screen
3. `grep ERROR` receives it and filters it
4. What survives gets printed

Notice that `grep` has no file name after it. It does not need one — it is reading from the pipe.

Most of these tools follow the same convention: given a file name, read the file; given none, read whatever comes in through the pipe. That one rule is what makes them all connectable.

## Chains

Pipes stack. Each stage takes what the last one produced:

```
grep INFO server.log | wc -l
```

`grep` pulls out the routine lines, `wc -l` counts them, and you get a single number back. Three lines of thinking, one line of typing.

You can keep going:

```
cat server.log | grep -v INFO | wc -l
```

Take the log, drop the routine lines, count what is left. Nothing here is a special "log analysis" tool — it is three general commands wired together.

## Building a chain without guessing

Do not write a four-stage pipe and hope. Build it one stage at a time and look at the output after each:

```
cat server.log
cat server.log | grep -v INFO
cat server.log | grep -v INFO | wc -l
```

Each step is checkable. When the answer at the end looks wrong, you already know which stage to suspect.

This is exactly how to read a long pipeline an AI agent hands you: cover everything after the first `|` and ask what the first part produces. Then uncover one stage at a time. A ten-stage pipeline is never complicated at any single point.

## Where it goes next

Combine what you already have and the pipe becomes genuinely powerful:

```
find . -name "*.log" | wc -l
```

That counts log files anywhere in the project — a question neither command could answer alone.

## Try it

1. `cat server.log` — the whole file, six lines.
2. `cat server.log | grep ERROR` — the same data, filtered down to two.
3. `grep INFO server.log | wc -l` — a count of the routine lines instead of the lines themselves.

Step 3 is worth a second look: the output changed shape entirely. Lines went in, a number came out. Each stage in a pipe is free to transform, not just filter.
