Bash
GLOBIGNORE 是如何運作的?
根據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
為什麼
..
從匹配列表中刪除?據我所知,模式.
不匹配..
,是嗎?
向下滾動…
當設置且不為空時,文件名
.
和..
總是被忽略。GLOBIGNORE
大多數時候,不希望包含
.
和..
作為萬用字元匹配,因為它們不代表目錄中的文件——它們是使目錄導航工作的黑客。其實點文件的起源是命令早期版本的一個bugls
。作者打算從列表中排除.
和..
,但意外排除了所有以 . 開頭的文件.
。因此點文件從ls
. Shells 通過隱藏點文件(如ls
. 然而,這樣做的方式又是一個 hack:.
只有當點在模式中沒有明確匹配時,才會排除以開頭的文件。所以模式.*
包括.
和..
。為了保持與現有腳本的兼容性,現代 shell 仍然包括
.
and..
(除了 zsh,在這個問題上它像許多其他人一樣具有更理智但不向後兼容的行為)。但是,如果您設置GLOBIGNORE
,則您使用的是特定於 bash 的功能,這表明您對向後兼容性不感興趣。因此模式匹配更改為排除.
所有..
模式匹配。設置
GLOBIGNORE=.
排除了無論何時設置都會自動排除的文件GLOBIGNORE
,因此它相當於shopt -s dotglob
except that.
並且..
從所有模式中排除。