Linux Basic — Iterating Through Lists
Iterating Through Lists
You have arrays. You have command output. You have files in a directory. Now you need to loop over them safely — which sounds trivial, but classic shell scripts get this wrong constantly and break on filenames with spaces, newlines, or shell metacharacters.
This chapter is the cure.
What You Will Learn
By the end of this chapter you will be able to:
- Loop over arrays with the correct quoting
- Loop over directory entries with globs, not
ls - Stream command output line-by-line with
while read - Use glob patterns including
**andextglob - Handle arbitrary filenames with
find … -print0 | xargs -0ormapfile -d ''
Topics in This Chapter
| # | Topic | Description |
|---|---|---|
| 1 | Looping Array Elements | for x in "${arr[@]}" and index loops |
| 2 | Looping Directory Listings | globs, hidden files, empty matches |
| 3 | Looping Command Output | while read vs subshell pitfalls |
| 4 | Glob Patterns | *, ?, […], **, extglob |
| 5 | find & xargs | NUL-safe iteration for any filename |
| 6 | Practice Exercises | Hands-on tasks |
The Iteration Decision Tree
What am I looping over?
│
├── A Bash array → for x in "${arr[@]}"
├── Files in cwd → for f in * (use a glob, never ls)
├── Recursive files → find -print0 | mapfile -d '' OR shopt -s globstar; for f in **/*
├── Lines from a file → while IFS= read -r line; do … done < file
├── Lines from a cmd → while IFS= read -r line; do … done < <(cmd)
├── Tokens from a str → IFS=… read -ra arr <<< "$str"
└── Numbers / range → for ((i=0; i<n; i++)) … OR for i in {1..10}
Memorise these five forms and 95% of “iterate over X” questions answer themselves.
The Forbidden Idiom
# ❌ NEVER do this
for f in $(ls); do …
for f in $(find . -type f); do …
Both word-split on $IFS and glob-expand the result. Any filename with a space, tab, glob char (*, ?, [), or newline breaks the loop. Use a glob, mapfile, or find -print0.
Next → Looping Array Elements