l1ackers
Not marked. Sign in and it follows you.

~/tutorials/023-the-loop-and-the-one-that-fails.md

023: The loop over a list, and the one that fails

Lesson five showed the loop as a shape. Field work runs it over real targets, watches one of them fail, and does not lose the rest. A loop that stops at its first failure is a loop that never finishes on real data, and real data always has a failure in it.

The census

for f in ~/news/*; do grep class: $f; done

Every file, one line each, the site's own category for the story it carries. Eleven files at the time of writing and twelve lines out, because one file says class twice: once as frontmatter and once in a sentence about flaw classes. That is not a bug in the loop. It is the loop being more honest than the summary you would have written by eye, and it is why the census runs at all.

Which one failed

Point the loop at a word one file forgot:

for f in ~/news/*; do grep -i cve $f | wc -l; done
1
0
2
2
1
1
1
1
2
1
3

One count per file, in order, and the zero in position two is the npm malware story: a supply-chain piece with no CVE in it. The loop did not stop. Every other file still answered, and the failure is sitting in the output with a row of its own, exactly where you can see it.

That is the design worth copying. grep with no match prints nothing, a pipe over nothing counts zero, and the loop glues eleven answers into one column: failures included, in their place, indistinguishable in shape from successes. Compare that to the alternative of opening eleven files by hand, where the natural human move is to skip the one that looks boring and never notice the zero.

The loop that fails outright

for f in ~/nope/*; do grep -i cve $f; done
for: ~/nope/*: no such directory

A directory that does not exist is not a target that failed, it is a question that never started, and the shell says which. Read the difference: a zero in the census means "asked, nothing matched". The refusal means "never asked". One is data. The other is a typo, and confusing them is how an empty result gets reported as a finding.

Keeping the totals straight

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

Fifteen lines across the month, and the per-file column above adds up to the same fifteen. Two commands that should agree, a third way to check your own work. When they do not, one of your loops is not walking what you think it walks, and counting at the joints is how you found out.

Try it

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

  1. Run the census and read the twelve lines against the eleven files. Which file spoke twice, and what is the second class doing there?
  2. Run the CVE census. Which file is the zero, and would you have found it reading by eye?
  3. Point the loop at a directory that does not exist and read the refusal. Say the difference between that answer and a zero in the column.
  4. Build the census for date: lines instead, then say how many of the eleven arrived in September without counting them yourself: the loop hands you the column and grep 2026-09 narrows it.

Counts age as the news grows, and this lesson is part of the tree now. The column is the current truth.

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