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

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →