Search code examples
bashantwildcardglobextglob

Does a double-asterisk wildcard mean anything apart from `globstar`?


I have an Ant build.xml script that includes the following snippet:

<fileset dir="${project.home}/${project.lib}">
    <include name="**/*.jar"/>
</fileset>

According to the answers to this question and the Bash documentation, the double-asterisk is indicative of globstar pattern-matching:

globstar

If set, the pattern ‘**’ used in a filename expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a ‘/’, only directories and subdirectories match.

This seems to be the sense in which whoever wrote the code meant it to work: locate all .jar files within the project library directory, no matter how many directories deep.

However, the code is routinely executed in a Bash shell for which the globstar setting is turned off. In this case, it seems like the double asterisk should be interpreted as a single asterisk, which would break the build. Nevertheless, the build executes perfectly well.

Is there any scenario outside of globstar for which the Bash shell will interpret ** in any way differently than *? For example, does the extglob setting alone differentiate the two? Documentation on this seems to be sparse.


Solution

  • You present part of an Ant build file. What makes you think that bash syntax or the settings of any particular bash shell has anything to do with the interpretation of the contents of that file? Ant implements its own pattern-matching; details are documented in the Ant User Manual, and in particular, here: https://ant.apache.org/manual/dirtasks.html#patterns.

    As for bash and the actual questions you posed,

    Is there any scenario outside of globstar for which the Bash shell will interpret ** in any way differently than *?

    In the context of arithmetic evaluation, * means multiplication, whereas ** means exponentiation.

    Bash's globstar option affects how ** is interpreted in a bash pathname expansion context, and nothing else. If globstar is enabled then ** has different effect in that context than does * alone; if it is not enabled then ** is just two * wildcards, one after the other, which does not change which file names match.

    Other than in those two contexts I don't think ** has any special meaning to bash at all, but there are contexts where * by itself is meaningful. For example, $* is a special variable that represents the list of positional parameters, and if foo is an array-valued variable then ${foo[*]} represents all the elements of the array. There are a few others. Substituting ** for * in those places changes the meaning; in most of them it creates a syntax error.

    For example, does the extglob setting alone differentiate the two?

    The bash manual has a fairly lengthy discussion of pathname expansion (== filename expansion). There are several options that affect various aspects of it, but the only one that modulates the meaning of ** is globstar.

    The noglob option disables pathname expansion altogether, however. If noglob is enabled then * and ** each represents itself in contexts where pathname expansion otherwise would have been performed.