GLOBIGNORE 如何运作?

Ern*_*t A 16 shell bash filenames wildcards

根据 bash 的手册页:

   GLOBIGNORE
          A colon-separated list of patterns defining the set of filenames
          to be ignored by pathname expansion.  If a filename matched by a
          pathname  expansion  pattern also matches one of the patterns in
          GLOBIGNORE, it is removed from the list of matches.
Run Code Online (Sandbox Code Playgroud)

然而在实践中...

$ bash --noprofile --norc
bash-4.2$ touch .bar
bash-4.2$ echo .*
. .. .bar
bash-4.2$ GLOBIGNORE=.
bash-4.2$ echo .*
.bar
Run Code Online (Sandbox Code Playgroud)

为什么..从匹配列表中删除?据我所知,模式 .不匹配..,是吗?

Gil*_*il' 15

向下滚动

文件名...总是在GLOBIGNORE设置且不为空时被忽略。

大多数时候,不希望包含...作为通配符匹配,因为它们不代表目录内的文件——它们是使目录导航工作的黑客。实际上,点文件的起源是命令早期版本中的一个错误ls。作者打算从列表中排除...,但不小心排除了所有以.. 因此点文件从ls. Shells 紧随其后,隐藏了ls. 然而,这样做的方式又是一个黑客:.只有当点在模式中没有明确匹配时才会排除以开头的文件。所以模式.*包括...

为了保持与现有脚本的兼容性,现代 shell 仍然包含...(除了 zsh,它在这个问题上像许多其他人一样具有更明智但不向后兼容的行为)。但是,如果您设置了GLOBIGNORE,则您使用的是 bash 特定的功能,这表明您对向后兼容性不感兴趣。因此,模式匹配更改为从所有模式匹配中排除.和排除..

设置GLOBIGNORE=.排除了一个无论如何都会自动排除的文件GLOBIGNORE,所以它相当于shopt -s dotglob除了那个...而且从所有模式中排除。