l1ackers
Not marked. Sign in and it follows you.

~/tutorials/005-pipes.md

005: Pipes, or asking the tree a question

Lesson three showed you a tree you can walk. This one shows you how to ask it questions.

A filesystem is a database that never admitted it. ls gives you rows, grep is the WHERE clause, and the pipe is how you put them together. Once you have that, "how many news items mention CVE" stops being something you scroll for and becomes something you ask.

The pipe

ls | head -3

ls produces lines. | hands those lines to the next command as its input, and head -3 keeps three of them. The stages do not know about each other, which is exactly why pipes compose: each one does a single thing and passes the result on.

This shell supports head, tail, grep, wc -l, sort and uniq. It has no processes, so it cannot pipe into anything else, and it tells you that instead of failing quietly.

Counting

ls ~/news | wc -l

wc -l counts lines. As this was written the answer is 11, which is a claim you are allowed to check, because the command is one line above it.

If your number differs, the tree changed since this lesson was written. That is not a bug in the lesson. ls -l ~/news shows the dates, so you can see what moved. A number in a lesson is a claim like any other, and this site exists so you can check claims.

The same is true of a sentence about the shell itself. Everything these lessons say about what a command can do was true when it was written, and the shell is allowed to change underneath it. Both of those are true at once: the lesson is honest, and the lesson can go stale. The way to hold them is not to trust either. Run it.

Filtering

ls ~/news | grep 2026-09
ls ~/news | grep -i aws

grep keeps the lines matching a pattern, and everything above searches the names. That is all this shell can do in one pass: there is no recursive form, so searching inside the files means one cat at a time. Worth knowing before you assume a quiet result means nothing is there. The -i matters for the same reason: the same idea written CVE and cve and Cve is one idea, and the wrong case is how you miss it.

Three stages, then:

ls ~/news | grep 2026-09 | wc -l

Nine at the time of writing. On a real filesystem this is how you answer questions you would otherwise guess at.

Walking a list

for f in ~/news/*; do grep -i cve $f; done

for runs a command once per item. The glob expands against the tree, $f becomes the current item, and the body is another pass through this same interpreter -- the loop is not a program, and nothing starts anywhere when you run it.

This is the shape that answers questions a single command cannot: how many files say a word, which ones changed, what a pattern looks like everywhere at once. Your own shell calls it a loop too, and the syntax is the same one.

Reading a result you did not expect

ls ~/news | grep 2026-09 | head -3

Then take one of the names you saw and read it:

cat ~/news/<the-name-you-saw>.md | head -20

You are doing by hand what a script would do, which is the point. The reason to learn the manual version first is that you cannot debug a pipeline you never built.

Try it

Each of these has one answer, and the shell gives it to you. Check yourself.

  1. How many lessons are there? Start with ls ~/tutorials.
  2. How many news items were published in September?
  3. How many mention CVE inside the files, not just in their names? Use the loop above with grep -i cve. Fifteen lines at the time of writing, across the news you can see.
  4. Which is the newest news item, by name?
  5. Take the newest item and find the line that says what a reader should do about it.

<!-- claim: 15 = for f in ~/news/*; do grep -i cve $f; done | wc -l -->

Number five is the real exercise. The answer is one line in one file, and finding it is the skill. grep with the right word gets you there faster than reading top to bottom. Both work. One of them scales.

Not marked. Sign in and it follows you.
l1ackers · shell this is a way in, not a requirement
$