Reading — step 1 of 5
Learn
Loops
Bash loops iterate over the things shells care about: words, lines, files, and number ranges. The syntax is small; the skill is choosing what to feed the loop — and one famous trap when the input is lines rather than words.
for: over a list of words
for fruit in apple banana cherry; do
echo "I like $fruit"
done
for x in LIST walks whatever words follow in — and those words usually come from an expansion:
for f in *.txt; do # glob: every .txt file, safely (spaces intact!)
echo "processing $f"
done
for i in {1..5}; do # brace expansion: 1 2 3 4 5
echo "$i"
done
for i in $(seq 1 "$n"); do # seq when the bound is a VARIABLE ({1..$n} does NOT expand)
…
done
That last comment earns its place: brace ranges are expanded before variables are substituted, so {1..$n} is the literal string {1..$n} — a classic gotcha. Variable bounds want seq or the C-style form:
for (( i = 1; i <= n; i++ )); do # C-style, arithmetic context rules apply
total=$(( total + i ))
done
while: conditions and — crucially — lines
while (( n > 1 )); do
…
done
…but while's real day job in bash is reading input line by line:
while read -r line; do
echo "got: $line"
done
This loop consumes stdin until it runs out — the pattern for processing files and piped data (-r stops backslash-mangling; write it always). It matters because the alternative people invent — for line in $(cat file) — is wrong: unquoted expansion splits on all whitespace, so lines with spaces shatter into words. Lines want while read -r; words want for. Carve that distinction in; it's the difference between a script that works and one that works on your test file.
break and continue behave as everywhere. Infinite loops are while true; do … done — true being, in the spirit of last lesson, just a command that always succeeds.
Your exercise: Sum 1 to N
Read n, sum 1 through n, print. The accumulator, bash edition:
read n
total=0
for (( i = 1; i <= n; i++ )); do
total=$(( total + i ))
done
echo "$total"
Same three graded details as every track (initialize before the loop; <= not <; print after) plus one bash-specific: don't reach for {1..$n} — you now know why it silently fails, and the C-style for handles variable bounds natively. Fourth language, same kata — and that's deliberate: when the pattern is muscle memory, the language differences are all you have left to learn, which is exactly the point of a fundamentals track.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…