Small tools, joined by pipes
Each tool does one thing to lines of text. Join them with | and they answer real questions - like which client is hammering your site with failing requests.
Every program starts with three streams already open: standard input (where it reads), standard output (where it writes its results) and standard error (where it writes complaints). In a terminal, input is your keyboard and both outputs are your screen.
The pipe, |, rewires that. In a | b, everything a writes to standard output becomes b’s standard input. Neither program knows; each just reads and writes lines. So tools that each do one small job - keep matching lines, cut out a column, sort, count - combine into answers none of them could give alone.
- grep reads the log and writes out only the lines that end in 500.
- Each | hands one tool's output to the next tool's input. cut -d ' ' keeps the first space-separated field: the client's address. Plain cut splits on tabs, and this log has none.
- uniq only merges identical lines that sit next to each other - so sort goes first and lines the twins up.
- sort -rn ranks the counts biggest first, head -1 keeps the top line, and > saves it to a file instead of the screen.
- Error messages travel on standard error, which a pipe does not carry. They still reach your screen, so a failing step cannot hide.
Find the noisy client
Your shop’s access log has one line per request: the client’s address first, the status code last. Something is failing a lot. Find out who.
Why does the pipeline sort before uniq -c?
uniq compares each line with the one before it. Unsorted, the same address appears in several separate runs and gets counted several times, in pieces. Sorting first makes every copy adjacent.
Redirection: where the output goes
Pipes connect programs. Redirection connects a program to a file:
> filewrites output to a file, replacing what was there.>> fileappends to the end.< filefeeds a file in as input.2> filesends standard error to a file.2> /dev/nullthrows errors away.
grep pattern missing.txt | wc -l prints 0, plus 'grep: missing.txt: No such file or directory' on screen. Why did the error not get counted?
A pipe connects standard output to standard input and nothing else. The error went to standard error, which still points at your terminal - so you see it, and wc never does.
Everything above ran in your browser. Now try it in a real terminal: any Linux machine, a Mac's Terminal app, or Windows with WSL. Nothing to install beyond that.
Your own shell keeps a history. Ask it which commands you use most:
history | cut -c 8- | sort | uniq -c | sort -rn | headThen the classic “which files are biggest here?”:
du -a . 2>/dev/null | sort -rn | head -5Sources
Missions and quizzes above earn their own XP. This marks the lesson done.