0

I recently needed to use a Bash for loop to recurse through a few files in a directory:

for video in **/*.{mkv,mp4,webm}; do
  echo "$video"
done

After way too much time spent debugging, I realised that the loop was run even when the pattern didn't match, resulting in:

file1.mkv
file2.mp4
**/*.webm # literal pattern printed when no .webm files can be found

Some detailed searching eventually revealed that this is known behaviour in Bash, for which enabling the shell's nullglob option with shopt -s nullglob is intended to be the solution.

Is there a reason that this counter-intuitive behaviour is the default and needs to be explicitly disabled with nullglob, instead of the other way around? Or to put the question another way, are there any disadvantages to always having nullglob enabled?

Hashim Aziz
  • 4,074
  • 5
  • 38
  • 68

1 Answers1

1

From man 7 glob:

Empty lists

The nice and simple rule given above: "expand a wildcard pattern into the list of matching pathnames" was the original UNIX definition. It allowed one to have patterns that expand into an empty list, as in

xv -wait 0 *.gif *.jpg

where perhaps no *.gif files are present (and this is not an error). However, POSIX requires that a wildcard pattern is left unchanged when it is syntactically incorrect, or the list of matching pathnames is empty. With bash one can force the classical behavior using this command:

shopt -s nullglob

(Similar problems occur elsewhere. For example, where old scripts have

rm `find . -name "*~"`

new scripts require

rm -f nosuchfile `find . -name "*~"`

to avoid error messages from rm called with an empty argument list.)

In short, it is the behavior required to be POSIX compatible.

Granted though, you can now ask what the rationale for POSIX was to specify that behavior. See this unix.stackexchange.com question for some reasons/history.

user17732522
  • 53,019
  • 2
  • 56
  • 105
  • Great find with the link to Unix.SE, I suppose the reasons given there also apply to Bash and therefore answer my question about disadvantages of always having it enabled? If so I'll read it over when I get a chance. – Hashim Aziz Nov 29 '22 at 20:17
  • With `shopt -s nullglob`, Writing `ls -lah *.csv` in a directory with no csv files it lists ALL files. This is also wrong, could be even worse than the default behavior of passing `*.csv` to the program. Imagine if you had a command to delete all files, or only the specified on the CLI and you pass null to it, deleting all files/stuff instead only of the filtered ones. EDIT: found answer mentioning this: https://unix.stackexchange.com/questions/204803/why-is-nullglob-not-default – Dalibor Filus Feb 09 '23 at 17:57