When constructing a pattern that matches a file name such as /home/user/project/.git, how does one match the . character "explicitly" -- that is, without the use of shopt -s dotglob?
The manual at https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html states:
When a pattern is used for filename expansion, the character ‘.’ at the start of a filename or immediately following a slash must be matched explicitly, unless the shell option dotglob is set.
What, exactly, does it mean, to "be matched explicitly"?
And again, at http://www.tldp.org/LDP/abs/html/globbingref.html (in the Notes section at the end), the same notion is addressed:
Filename expansion can match dotfiles, but only if the pattern explicitly includes the dot as a literal character.
The note provides the following examples:
~/[.]bashrc # Will not expand to ~/.bashrc ~/?bashrc # Neither will this. # Wild cards and metacharacters will NOT #+ expand to a dot in globbing. ~/.[b]ashrc # Will expand to ~/.bashrc ~/.ba?hrc # Likewise. ~/.bashr* # Likewise. I fail to understand the inner workings of the last three examples, which will expand to include the "dotfile".
How, specifically, does placing the b in brackets after the . make this an "explicit" match in the example ~/.[b]ashrc? The subsequent examples are even more ambiguous to me. I simply fail to understand how manipulating the pattern in ways that seem completely unrelated to the . character cause the pattern to produce a match.
With regard to why I would like to avoid using shopt -s dotglob, the impetus for this question is rooted in the fact that I am writing these patterns for use in another program's configuration file. I want to exclude paths that contain, for example, "hidden .git directories", and I'm not sure that I have the ability to specify dotglob in any capacity.
In essence: What is the simplest means by which to match the . character by "being explicit"? Placing the next character in brackets "makes it work", but I'd like to know why; I feel like I'm "shooting in the dark" with that approach.
Any explanation as to the underlying behavior in this regard is much appreciated.
EDIT TO ADD:
Initially, it didn't seem relevant, but because people seem to be interested in the specifics of my use-case, I'll explain further.
I'm using a Host-Based Intrusion Detection software called Samhain. Samhain will "alert" whenever the filesystem is modified according to certain user-specified configuration parameters.
I don't want Samhain to alert when files within .git directories (that are located within certain parent directories) are created/modified/deleted. In Samhain, this type of exclusion is performed by defining "ignore rules". The exact specification of these rules is explained at http://www.la-samhna.de/samhain/manual/filedef.html , in 4.2. File/directory specification.
In short:
Wildcard patterns ('*', '?', '[...]') as in shell globbing are supported for paths. The leading '/' is mandatory.
So, I am trying to write an "ignore rule" that will match the .git directories in question, which will, in effect, cause Samhain to exclude them from its monitoring activities.
Initially, I tried this:
[IgnoreAll] dir = -1/home/user/project/*/*/.git This didn't work; Samhain still alerted whenever files inside those .git directories changed.
Upon finding the examples cited above, I tried this:
dir = -1/home/user/project/*/*/.[g]it With this change, Samhain ignores the files, as desired.
In posting this question, I was simply trying to understand why that change has the intended effect.
I will say, I feel less stupid given that the very pattern I was trying to use at first does indeed match the .git directories in question when I use "echo" test:
echo /home/user/project/*/*/.git So, it wasn't so much that I was misunderstanding something fundamental with regard to pattern-matching, globbing, or file-name expansion in Bash; to the contrary, there seem to be nuances with regard to how Samhain, in particular, implements pattern-matching in this context.
I have no idea why this doesn't work when applied in the context of Samhain's configuration file (obviously). Maybe somebody will be able to explain, given this edit.
.to be found, whatever the rest if it matches.Ignoredirective.” See my updated answer.