为什么每个目录都有“.”和“..”点?

为什么每个目录都有“.”和“..”点?

一个历史问题。我尝试寻找这个问题的答案,但没有运气。

每个目录都包含一个“.”和“..”,甚至ROOT(/)也包含“..”,但是为什么呢?从我承认的有限的角度来看,这两者似乎都是不必要的。

  1. 运行当前目录中的脚本./script.sh。但如果“。”不存在,那么我们就可以使用bash script.sh.

  2. 更改到父目录cd ..。但如果“..”不存在,那么我想可能存在一个命令,例如cd --parent 1(转到一个父目录)

因此,点和点点似乎不是强制性的,而是一种简写。

缺点是它们会阻止创建任何名为“.”的文件。或者 ”..”。此外,它们还可以使列出/操作以点开头的文件变得更加困难/容易出错。

rm -r .* # delete current and parent directory?

需要明确的是,我并不是要求改变。我只是好奇我们怎么会来到这里?为什么做出这样的选择而不是任何其他方式来引用这两个目录?

编辑:有些人投票否决了我的问题,但没有就如何改进它提供任何反馈。

答案1

.和目录..是 POSIX unix 规范的一部分。

您关于更改命令以使其在没有它们的情况下工作的建议将使事情变得更加复杂,而不是不那么复杂。还有历史原因。

如果我们不必.引用当前目录,你会怎么做?也许有一个空字符串?使用..父目录确实看起来像是一个快捷方式,但为系统中的每个命令添加选项以避免使用它也不是一个好的解决方案。一些(历史)系统还必须...引用两个父目录,但这可能只是一个 shell 快捷方式。

..目录在相对路径名中很有用,这是使内容可移植的好方法,通常比硬编码完整路径名更好。

传统上,该.目录包含在$PATH.后来人们意识到,在路径中包含当前目录存在安全风险——如果您cd访问的目录包含与系统命令同名的恶意可执行文件,该怎么办?因此它已从默认路径中删除,现在要运行当前目录中的内容,您需要通过说明确地执行此操作./command;使用bash command相反 会启动两个进程而不是一个。

答案2

运行当前目录中的脚本./script.sh。但如果“。”不存在,那么我们就可以使用bash script.sh.

是的,但这需要知道什么是正确的口译员。也许有人用 Perl 重写了它,但为了兼容性而保留了名称,或者名称实际上只是othertool,没有扩展名。运行它./othertool让系统通过 hashbang 行 ( ) 来处理这个问题#!。或其他幻数,因为程序也可以是二进制文件。当然,您也可以添加.PATH

不过,这是事后的合理化,因为我很确定 hashbang 行从一开始就不存在(即使现在它们也不是 POSIX)。

更改到父目录cd ..。但如果“..”不存在,那么我想可能存在一个命令,例如cd --parent 1(转到一个父目录)

是的,它可能存在。但这意味着每次您想使用相对路径时,都会变得更困难。你不能做类似的事情,mv ../foobar/blah .也许有些程序会包含某种方法来做到这一点,要么通过命令行选项,比如你的--parent,要么通过路径前缀的一些字符串,例如%up/foobar/blah,等等。

同样,您无法使相对符号链接指向树的更高级别。/foo/bar/link指向的符号链接/foo/other/file需要拼写出名称,而不仅仅是包含相对引用../other/file。重命名时链接会中断foo,或者必须有一种机制可以在任何重命名时重写任何此类符号链接......

即使不太常用,标准在文件系统树中向上移动的方式使类似的东西更加通用,并且在以下情况下通用更好需要。

此外,文件系统需要某种方法来查找给定目录的父目录才能cd --parent工作,并且直接而明显的实现是像与该目录相关的所有其他目录一样存储它,并使用特殊的名称。

.同样有用,因此您无需使用cp /some/where/file.txt .特殊方式来引用“此处”。虽然我记得,例如COPYDOS/Windows 上的命令默认以当前目录作为目标,例如 GNU find 和 GNU grep 默认-r从当前目录开始。但这也意味着每个程序都必须有一个当前目录的特殊情况。


当然,名称可能完全不同,并且例如禁止创建名称以点开头的其他文件可能不是一个坏主意。或者为这些特殊名称保留某些特定字符,并完全禁止在其他文件名中使用该字符。

相关内容