What's the proper way to do a for loop over a file mask?
E.g. if the mask doesn't expand to any file, then the loop should not run; else, it should run over all the files that it expands to.
The problem with naive approach is that if the *
doesn't expand to anything, then the whole loop will run once as if the *
part is an actual part of a filename (of a file that doesn't actually exist).
One way to do this is:
That will also filter directories out of the list, which might or might not be what you want.
If you want to keep directories, use
-e
instead of-f
.Another way to do it is to set the shell option
nullglob
(may not be available on all bash versions). Withnullglob
set, patterns which don't match any filename will result in nothing instead of being unaltered.(That leaves
nullglob
set for the duration of thefor
loop. You can unset it inside the loop instead of waiting for the end, at the smallish cost of executing theshopt -u
on every loop.)Use the
nullglob
shell option to make a wildcard that doesn't match anything expand into nothing instead of returning the wildcard itself: