我对符号链接和`..` 在 POSIX 下如何交互的理解是否正确

Lyn*_*ite 5 symlink filenames posix

我正在研究路径数学描述(例如文件路径,但也更抽象和通用)

定义的最棘手的事情之一是..(? 在链接的帖子中); 特别是它如何与符号链接交互。

我想检查一下我是否正确理解了 POSIX 规则。

POSIX 4.14

当进程解析现有目录条目的路径名时,整个路径名应如下所述解析。当进程解析要在解析路径名后立即创建的目录条目的路径名时,路径名解析在最后一个组件的路径前缀的所有组件都已解析后终止。然后由流程负责创建最终组件。... pathname 中的每个文件名都位于其前任指定的目录中(例如,在路径名片段 a/b 中,文件 b 位于目录 a 中)。...如果在路径名解析过程中遇到符号链接,...系统应使用符号链接的内容作为剩余路径名的前缀,如果有的话...解析的路径名应是刚刚创建的路径名的解析。如果生成的路径名不以 a 开头,则该路径名的第一个文件名的前身被视为包含符号链接的目录。特殊文件名点应指代其前任指定的目录。特殊文件名 dot-dot 应指代其前任目录的父目录。作为一种特殊情况,在根目录中,dot-dot 可能指的是根目录本身。.. dot-dot 可能指的是根目录本身。.. dot-dot 可能指的是根目录本身。..

所以我的理解是POSIX 说的是在解析..到父目录之前应该扩展符号链接。

这样对吗?

因此,对于规范化路径,POSIX 兼容方式的行为 realpath -P 是要求存在所有目录(但不是最终文件组件),并从左到右展开解析符号链接(一旦遇到),然后应用.. which也就是说,在处理路径的所有步骤中都必须读取文件系统。

我们可以将其与node.jsPath.normalize(甚至它的Path.posix.normalize)的行为进行对比——我认为这在许多编程语言中是相当正常的(Python23 os.path类似)。相当于realpath -s -m也就是说它完全忽略了某些目录可能是simlinks,或者可能不存在。 这很好,因为它根本不必接触文件系统。

如果我们采用已经以这种方式规范化的路径,并将其提供给一个确实触及文件系统的函数(例如fs.readFile)那么它相当于我们是否使用了规范化了路径realpath -L,即..在符号链接之前解析”

Bashcd也表现得好像它已经处理了它的参数,realpath -L除非你给它这个-P标志

我是否正确理解了 POSIX 规范,以及它与realpath、以及许多(大多数?)编程语言路径库的关系?

额外的问题:-P,有人有一个编程语言/库的例子(除了使用 shell 实用程序,如realpath),它具有符合 POSIX 规范的实现?(我相信 Python 3 pathlib.Path.resolve是正确的。虽然它也将相对路径转换为绝对路径。)

PSk*_*cik 2

... Unix 上是真实的目录条目,代表属于其父目录的真实文件(文件或目录)。

..不是用于剥离路径最后一段的路径解析关键字。为了解析 a ..,您首先需要解析包含它的目录。Nodejs 做错了。

$ mkdir -p /tmp/foo/bar/baz
$ ln -s /tmp/foo/bar/baz /tmp/symlink
$ realpath /tmp/symlink/..
  /tmp/foo/bar
$ node -e 'console.log(path.normalize("/tmp/symlink/.."))'
  /tmp
Run Code Online (Sandbox Code Playgroud)

(这些条目总是在创建目录时创建,并且它们被制作为到当前目录及其父目录的硬链接。它们是目录硬链接的一些罕见示例,因为系统通常不允许普通用户创建目录硬链接。

ls -ld这就是为什么每当您创建子目录时目录中的硬链接计数就会增加,以及为什么目录从硬链接计数 3 开始(它们的名称、. 和它们的_name/..)。子目录..是到当前目录的硬链接,从而增加了其硬链接计数。)