2019-06-17 10:00:50 +0100, Geoff Clare: > Stephane Chazelas <stephane.chaze...@gmail.com> wrote, on 16 Jun 2019: > > > > In > > > > files='\*x' sh -c 'ls -ld -- $files' > > > > We have an unquoted * in that unquoted $files. But here, if it > > was going to be used as a pattern (by the fnmatch() that would > > be applied to the list of files in the current directory), the * > > would end up being quoted by that unquoted \, so the filename > > generation is not done, a literal \*x is passed to ls. > > I think most, if not all, of your examples come down to a conflict > between two different POSIX requirements.
Those [1] to [11] points in my previous article identify 11 differences and exceptions most of which POSIX will have to specify somehow if they want to allow all existing behaviours in that regard, or IOW to tell applications what they can do portably. > In the last paragraph of > 2.13.1 it says "This escaping <backslash> is discarded". In the last > paragraph of 2.13.3 it says "If the pattern does not match any existing > filenames or pathnames, the pattern string shall be left unchanged". > > It seems to me that 2.13.1 should be interpreted as overriding 2.13.3, > as otherwise there would be no point in having that statement there. > The only place that discarding the backslash makes any difference is > if the pattern is used for something after the matching operation, and > the only way for that to happen is when a shell pathname expansion does > not match any files. But bash sticks to the 2.13.3 requirement and > uses the pattern unchanged (including the backslash). > > In the resolution of bug 1234 we should update 2.13.3 to say > something like "... left unchanged, except that escaping <backslash> > pattern characters in parts of the pattern that are not affected by > shell quoting shall be discarded as specified in [xref to 2.13.1]". [...] I don't think you got my point. The question is when filename generation is done at all in that case you picked up. In: files='\*x' printf '%s\n' $files bash5 (and for other reasons, shells like ksh93 or dash that don't treat an unquoted \ as a wildcard quoting operator when used in pathname expansion) does filename generation, other shells (zshsh, kresh, bash4) don't. For them, it's not a case of whether the pattern matches any file or not, there is no pattern matching at all. In ksh93/dash, that will expand to all the filenames that start with \ and end in x, and \*x if there's no match. In bash5, that will expand to the *x file if it exists and \*x if not (no match) In bash4, zshsh, kresh, there's no filename generation at all, that expands to \*x regardless of whether there's a \*x, *x or \anythingx file in the current directory. -- Stephane