GLOBIGNORE如何运作?


15

根据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.

但是在实践中...

$ bash --noprofile --norc
bash-4.2$ touch .bar
bash-4.2$ echo .*
. .. .bar
bash-4.2$ GLOBIGNORE=.
bash-4.2$ echo .*
.bar

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

Answers:


14

向下滚动

设置时,文件名...始终被忽略GLOBIGNORE,不为null。

在大多数情况下,不希望包含...作为通配符匹配,因为它们不表示目录中的文件-它们是使目录导航正常工作的黑客。实际上,点文件的来源是ls命令的早期版本中的错误。作者的意图是排除...从清单中删除,但无意中排除了所有以.。这样,点文件就从中隐藏了ls。炮弹紧随其后,隐藏了点文件ls。但是,这样做的方式又是一次黑客:开头的文件.仅在模式中未明确匹配点时才排除。因此,模式.*包括...

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

设置会GLOBIGNORE=.排除一个文件,该文件无论何时GLOBIGNORE设置都会自动被排除,因此它等效于shopt -s dotglob.并且..会从所有模式中排除。


1
实际上,我只是意识到设置GLOBIGNORE仅忽略.并且..采用无斜杠模式,并且GLOBIGNORE过滤文件路径而不是文件名。GLOBIGNORE=.; echo .*将不包含.nor ..,但GLOBIGNORE=.; echo ./.*(或echo /bin/.*)将包含!要忽略...从所有的水珠,它看起来像你需要shopt -s extglobGLOBIGNORE='?(*/)@(.|..)'
斯特凡Chazelas

1
实际上,不,GLOBIGNORE='?(*/)@(.|..)'不会排除....*/fooGLOBIGNORE='?(*/)@(.|..)?(/*)'将打破水珠像./*...
斯特凡Chazelas

3

在标题为“路径名扩展”的部分中man bash

当设置了GLOBIGNORE时,文件名“。”和“ ..”始终被忽略,并且不为null。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.