Thanks, I installed that, along with the attached followup which documents some other globbing pitfalls.

By the way, brace expansion is not part of globbing: it's a prepass over the shell command and it operates independently of file names. Brace expansion does not work when doing pattern matching in 'case' statements, for example. So I adjusted the example to not imply that brace expansion cares whether files exist.
From 63ffa8e950de5d25f32464b31885e5363c55e8cc Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 6 May 2025 05:04:04 -0700
Subject: [PATCH] More shell patterns to avoid

* doc/autoconf.texi (Shell Pattern Matching):
Improve on the recent discussion about brace expansion.
---
 doc/autoconf.texi | 55 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 42 insertions(+), 13 deletions(-)

diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 129e8018..12734446 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -16272,25 +16272,54 @@ File names are case insensitive, so even names like
 @section Shell Pattern Matching
 @cindex Shell pattern matching
 
-Nowadays portable patterns can use negated character classes like
-@samp{[!-aeiou]}.  The older syntax @samp{[^-aeiou]} is supported by
-some shells but not others; hence portable scripts should never use
-@samp{^} as the first character of a bracket pattern.
+Portable patterns should avoid the following constructs:
 
-Outside the C locale, patterns like @samp{[a-z]} are problematic since
-they may match characters that are not lower-case letters.
+@itemize @bullet
+@item
+A bracket expression like @samp{[a-z]} outside the C locale.
+This pattern may match characters that are not lower-case letters.
+Outside the C locale, use @samp{[[:lower:]]} instead,
+or to match just lower-case ASCII letters use
+@samp{[abcdefghijklmnopqrstuvwxyz]}.
+
+@item
+A bracket expression starting with @samp{^}.
+For example, @samp{[!-aeiou]} is portable, but @samp{[^-aeiou]} is not.
 
-Patterns with braces are, although not specified by POSIX, supported
-by most shells.  Not so by AIX 7.3 @command{/bin/sh}, though:
+@item
+When matching file names, a pattern containing @samp{*}, @samp{?} or
+@samp{[...]} that might match the file names @samp{.} or @samp{..}.
+For example @samp{.*} might match @samp{.} and @samp{..}, but it might not.
+
+@item
+Any of the following characters,
+unless quoted or escaped or in a bracket expression:
 
 @example
-$ @kbd{ls -1 sequence000.c sequence999.c}
-sequence000.c
-sequence999.c
-$ @kbd{ls -1 sequence@{000,999@}.c}
-ls: 0653-341 The file sequence@{000,999@}.c does not exist.
+! # % = [ ] ^ @{ @} ~
 @end example
 
+An unescaped @samp{[} that does not introduce a bracket expression is
+problematic because, for example, @samp{a*[} might match the file name
+@samp{abc[}, but it might not.
+
+Curly braces are problematic because POSIX allows but does not require
+brace expansion.  For example, the shell command @samp{echo a@{b,c,d@}e}
+outputs @samp{abe ace ade} with Bash, but @samp{a@{b,c,d@}e} with Dash.
+
+@item
+Backlashes in bracket expressions, unless doubled.
+For example, @samp{[\\^]} is portable, but @samp{[\^]} is not.
+
+@item
+An unescaped backslash at pattern end.
+
+@item
+A NUL byte.
+More generally, a NUL byte should never appear anywhere
+in a portable shell script.
+@end itemize
+
 @node Shell Substitutions
 @section Shell Substitutions
 @cindex Shell substitutions
-- 
2.48.1

  • [PATCH] doc: ... Bruno Haible via Patches for autoconf - the GNU build system
    • Re: [PAT... Paul Eggert
      • Re: ... Bruno Haible via Patches for autoconf - the GNU build system

Reply via email to