Differences between revisions 2 and 13 (spanning 11 versions)
Revision 2 as of 2008-11-22 14:08:47
Size: 2007
Editor: localhost
Comment: converted to 1.6 markup
Revision 13 as of 2016-05-08 15:03:21
Size: 132
Editor: geirha
Comment: spam
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
`nullglob` is a Bash shell option which affects the results of [[glob]] expansion.

Normally, when a glob which does not match any filenames is expanded, it remains unchanged. Thus, you get results like this:
 {{{
 $ rm *.bak
 rm: cannot remove `*.bak': No such file or directory}}}

The unmatched glob `*.bak` is not replaced with anything; it is passed to `rm` directly as if it were a literal filename. `rm` then tries to unlink it, and fails with a reasonable error message.

However, this causes some undesired results in programming. Consider an [[BashFAQ/005|array]] populated like this:
 {{{
 # Bash
 files=(*)
 echo "There are ${#files[*]} files here."}}}

This fails if there are no files which match the glob -- it will report one file, because the array is loaded with the single element `*`.

The `nullglob` option lets us avoid this problem. If it is set, then an unmatched glob is swept away entirely -- replaced with a set of zero words -- instead of remaining in place as a single word.
 {{{
 # Bash
 shopt -s nullglob
 files=(*)
 echo "There are ${#files[*]} files here."}}}

`nullglob` is '''not''' on by default because there are other cases where its behavior would be extremely disconcerting. For example, `ls` behaves quite unexpectedly if an unmatched glob is removed from the argument list:
 {{{
 shopt -s nullglob
 ls *.xyzqj
 # This will list all the files in the current directory
 # just as if the user had typed "ls" with no args.}}}

`nullglob` by itself may not be sufficient for all cases. A glob does not, by default, match files whose names begin with a period, unless the glob itself also begins with a period. If so-called "hidden files" should also be matched by a glob, then one may wish to use the `dotglob` option.
 {{{
 # Bash
 shopt -s dotglob
 shopt -s nullglob
 files=(*)
 echo "There are ${#files[*]} files here."}}}

Just remember that these options remain in effect for the current shell process until disabled.
Redirect to [[glob#nullglob]].
/* all information that this article once contained was carefully fitted into the glob article. */

Redirect to glob#nullglob.

NullGlob (last edited 2016-05-08 15:03:21 by geirha)