Bash – What does `.[].foo[]` do in bash? Why does it match `..`

bashshellwildcards

Look at the following:

$ echo .[].aliases[]
..
$ echo .[].foo[]
..
$ echo .[].[]
..
$ echo .[].xyz[]
..
$ echo .xyz[].xyz[]
.xyz[].xyz[]
$ echo .xyz[].[]
.xyz[].[]

Apparently this seems to be globbing something, but I don’t understand how the result comes together. From my understanding [] is an empty character class. It would be intuitive if

  • it matched only the empty string; in this case, I’d expect bash to reproduce in its entirety since nothing matches it in this directory, but also match things like ..aliases (in the first example),
  • or nothing at all; in this case, I’d expect bash to reproduce the string in total, too.

This is with GNU bash, version 4.4.23(1)-release.

Best Answer

The [ starts a set. A set is terminated by ]. But there is a way to have ] as part of the set, and that is to specify the ] as the first character. As an empty set doesn't make any sense, this is not ambiguous.

So your examples are basically all a dot followed by a set that contains a dot, therefore it matches two dots.

The later examples don't find any files and are therefore returned verbatim.