grep -c exits non-zero on zero matches

This looks like sensible defensive shell, and it has a bug:

n=$(grep -c pattern file || echo ERR)

When nothing matches, grep -c prints 0 and exits 1. The || branch
fires anyway, so $n becomes 0 followed by ERR on the next line — the
"error" fallback corrupts a perfectly good count.

The root cause is grep's three-way exit status:

So exit 1 must be treated as success when counting. Either drop the fallback
entirely:

n=$(grep -c pattern file) || true

or distinguish real errors explicitly:

n=$(grep -c pattern file)
case $? in
2) echo "grep failed" >&2; exit 1 ;;
esac

The general lesson: || guards assume "non-zero means failure," and several
classic tools (grep, diff, cmp) use exit codes as ternary answers, not
pass/fail.