Control and functions
Loop over arguments and files
Iterate over exact command-line arguments and handle a glob that may match nothing.
10 minute lesson
"$@" expands to one shell word per original argument. It is the safe way to forward or loop over all supplied values — spaces inside an argument stay inside it.
Loop over arguments
Print every input path:
for path in "$@"; do
if [[ -e $path ]]; then
printf 'exists: %s\n' "$path"
else
printf 'missing: %s\n' "$path" >&2
fi
done
Test paths containing spaces, dashes, and wildcard characters. Each must remain one value:
./check-paths 'weekly report.txt' notes.md
# exists: weekly report.txt
# missing: notes.md
The quotes carry the whole guarantee. Unquoted $@ or $* splits weekly report.txt into two words, and the loop checks two files that don’t exist. Same inside the loop body: "$path" keeps the value whole.
Loop over files with globs
For files on disk, let the shell expand a glob:
for logfile in /var/log/nginx/*.log; do
printf 'compressing %s\n' "$logfile"
done
The expansion happens before the loop starts, and each match arrives as one word. Filenames with spaces are safe with no extra effort.
One trap remains: a glob that may match nothing. When no file matches, Bash leaves the pattern in place, and your loop runs once with the literal string /var/log/nginx/*.log as its value. The script then claims to compress a file that doesn’t exist. Fix it with nullglob:
shopt -s nullglob
for logfile in /var/log/nginx/*.log; do
printf 'compressing %s\n' "$logfile"
done
With nullglob set, an unmatched glob expands to nothing and the loop body never runs. Test both states: a directory with matching files and an empty one.
Do not parse ls
Old tutorials show for f in $(ls). Don’t copy it. The output of ls is text, and command substitution word-splits it, so any filename with a space shatters into pieces. There is no quoting fix for this pattern — the information is already destroyed.
Work from arguments, globs, find -print0, or another structured source. The find variant gets its own lesson in the next module.
Lesson completed