The pipe: stdout of one, stdin of the next
Redirection connects a command to a file. The pipe | connects a command directly to another command: the stdout of the left side becomes the stdin of the right side.
grep error app.log | head -n 5grep finds every error line, and head keeps only the first five. No temporary file needed.
This is the famous Unix philosophy: many small programs, each doing one thing well, snapped together like plumbing. You already know grep, head, tail, and sort. One more joins here: wc -l (word count, -l for lines) counts the lines it receives.
Code exercise · bash
Run two pipelines. The first finds lines containing 7 and keeps the first three. The second counts 200 lines without any file at all (tr -d ' ' strips the padding spaces some systems put around wc's number).
tee: save a copy mid-pipeline
A pipe sends output onward and keeps nothing. Sometimes you want both: keep processing and keep a copy, without running the expensive left side twice. tee file does that — placed in the middle of a pipeline, it writes everything passing through into the file AND passes it along unchanged to the next command. (The name comes from the T-shaped junction in plumbing, which splits one flow into two.)
grep error app.log | tee errors.txt | wc -l
One grep, two results: errors.txt holds the matching lines for later, and wc still gets to count them now.
Code exercise · bash
Run it. The pipeline counts how many of the numbers 1..100 contain a 7, and tee snapshots grep's full output into sevens.txt on the way past — head then proves the file is really there.
Quiz
In `grep error app.log | wc -l`, what exactly does wc -l receive as input?
Code exercise · bash
Your turn. In ONE line with two pipes: generate 1 to 30 with seq, keep only lines containing the digit 2 with grep, and count them (finish with `wc -l | tr -d ' '`). Expected output: ``` 12 ```