Ben*_*son 1 shell bash wildcards dot-files bash-expansion
在构建与文件名匹配的模式时,例如/home/user/project/.git,如何.“显式”匹配字符——也就是说,不使用shopt -s dotglob?
https://www.gnu.org/software/bash/manual/html_node/Filename-Expansion.html 上的手册指出:
当模式用于文件名扩展时,字符 '.' 除非设置了 shell 选项 dotglob,否则在文件名的开头或紧跟在斜杠后面的必须显式匹配。
“明确匹配”究竟是什么意思?
同样,在http://www.tldp.org/LDP/abs/html/globbingref.html(在最后的Notes部分),同样的概念得到解决:
文件名扩展可以匹配点文件,但前提是模式明确包含点作为文字字符。
该说明提供了以下示例:
~/[.]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.
Run Code Online (Sandbox Code Playgroud)
我无法理解最后三个示例的内部工作原理,这些示例将扩展为包括“dotfile”。
具体来说,如何在示例b中将括号放在.使其成为“显式”匹配之后~/.[b]ashrc?随后的例子对我来说更加模棱两可。我只是无法理解以与.字符完全无关的方式操作模式如何导致模式产生匹配。
关于为什么我想避免使用shopt -s dotglob,这个问题的动力源于我正在编写这些模式以在另一个程序的配置文件中使用这一事实。我想排除包含例如“隐藏.git目录”的路径,但我不确定我是否有能力以dotglob任何身份进行指定。
本质上:.通过“显式”匹配字符的最简单方法是什么?将下一个字符放在括号中“使它起作用”,但我想知道为什么;我觉得我在用这种方法“在黑暗中拍摄”。
非常感谢对这方面潜在行为的任何解释。
编辑添加:
最初,它似乎并不相关,但因为人们似乎对我的用例的细节感兴趣,我将进一步解释。
我正在使用名为Samhain. 每当根据某些用户指定的配置参数修改文件系统时,Samhain 都会“发出警报”。
我不希望 Samhain 在.git创建/修改/删除目录中的文件(位于某些父目录中)时发出警报。在 Samhain 中,这种类型的排除是通过定义“忽略规则”来执行的。这些规则的确切规范在http://www.la-samhna.de/samhain/manual/filedef.html中进行了解释4.2. File/directory specification。
简而言之:
Wildcard patterns ('*', '?', '[...]') as in shell globbing are supported for paths. The leading '/' is mandatory.
因此,我正在尝试编写一个“忽略规则”来匹配有.git问题的目录,这实际上会导致 Samhain 将它们从其监视活动中排除。
最初,我试过这个:
[IgnoreAll]
dir = -1/home/user/project/*/*/.git
Run Code Online (Sandbox Code Playgroud)
这没有用;每当这些.git目录中的文件发生更改时,Samhain 仍会发出警报。
找到上面引用的例子后,我尝试了这个:
dir = -1/home/user/project/*/*/.[g]it
Run Code Online (Sandbox Code Playgroud)
通过此更改,Samhain 会根据需要忽略这些文件。
在发布这个问题时,我只是想了解为什么这种变化会产生预期的效果。
我会说,我觉得不那么愚蠢,因为.git当我使用“echo”测试时,我最初尝试使用的模式确实与有问题的目录匹配:
echo /home/user/project/*/*/.git
Run Code Online (Sandbox Code Playgroud)
所以,并不是我误解了 Bash 中的模式匹配、通配符或文件名扩展的基本原理;相反,特别是 Samhain 如何在这种情况下实现模式匹配似乎存在细微差别。
我不知道为什么在 Samhain 的配置文件的上下文中应用时这不起作用(显然)。鉴于此编辑,也许有人能够解释。
当模式用于文件名扩展时,字符 '.' 除非设置了 shell 选项 dotglob,否则在文件名的开头或紧跟在斜杠后面的必须显式匹配。
这只是意味着 globs *、?和[...]不匹配.文件名开头的 a 。如果要匹配.文件名开头的 a,则不能使用 glob,必须.明确键入 the 。例如:
$ echo ????
Work
$ echo .???
.gem .pki .ssh .vim
Run Code Online (Sandbox Code Playgroud)
并回答你的另一个问题:
具体来说,如何在示例
b中将括号放在.使其成为“显式”匹配之后~/.[b]ashrc?
仅仅因为您使用了 glob 模式并不意味着整个模式不再是“明确的”。在~/.[b]ashrc,例如,人物/.ashrc都明确地匹配。但是,[b]是 glob 模式,也不是显式匹配。(从技术上讲,~是波浪号扩展并且比 glob 扩展更早执行,因此它也是显式匹配。)但是其他字符,包括.,确实显式匹配,这就是~/.[b]ashrc匹配的原因~/.bashrc。
对于比较,~/?[b]ashrc将不匹配~/.bashrc,因为.不再显式匹配。
| 归档时间: |
|
| 查看次数: |
2385 次 |
| 最近记录: |