为什么Unix通配符“*”不包括“.*”?

3
考虑一个只有一个文件 .foo 的目录。执行 rm -rf * 不会删除 .foo 文件,而只有执行 rm -rf .* 才能删除。为什么会这样呢?(我猜这与默认的... 有关,但是设计上的原理是什么?当它们应该被删除时,我倾向于留下点文件。)

2
这是一个古老的惯例:以点开头的文件名对于 shell 来说是“隐藏”的。 - Basile Starynkevitch
4个回答

13
根据Rob Pike的说法,文件名以点开头的文件应该被“隐藏”的整个概念是由于软件漏洞导致的
特别是,他说:

首先,设定了一个不好的先例。许多其他懒惰的程序员通过做出相同的简化引入了漏洞。实际上以句点开头的文件通常会被跳过,而它们本应被计算在内。

第二,更糟糕的是,创造了“隐藏”或“点”文件的概念。[...]

我非常确定隐藏文件的概念是一种无意中的后果。这绝对是一个错误。

历史意外事故除外,从通配符扩展中排除隐藏文件是一个很好的保守设计决策。否则,像rm *这样的命令可能会比用户预期造成更大的损害。

3
这是因为以字符“.”为前缀的文件通常是隐藏的,并且不属于正常的globbing扩展。这意味着,在包含控制文件或目录(例如 .svn)的目录中,您不会得到混乱的glob。当您使用 * 时,通常希望将其扩展为正常文件。

1

来自Bash手册

当使用模式进行文件名扩展时,除非设置了shell选项dotglob,否则必须显式匹配以“.”开头的文件名或紧跟斜杠后面的“.”字符。在匹配文件名时,斜杠字符必须始终显式匹配。在其他情况下,“.”字符不会被特殊处理。

至于理由,我只能猜测。我想这是为了防止您意外操作您不知道存在的文件(请记住,ls不会显示.foo)。


1
这背后的设计理念是,例如.foo是一个隐藏文件。对整个目录进行不稳定的操作可能会造成比预期更大的损害。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接