Linux 如何处理多个连续的路径分隔符(/home////username//file)?

Fal*_*rri 130 directory slash filenames

我正在处理将文件位置传递给 scp 子进程的 python 脚本。这一切都很好,但我处于这样一种情况,我可能最终将一个路径与一个文件名连接起来,这样路径中就有一个双 ' /。我知道 bash 不关心您是否有多个文件分隔符,但我想知道如何纠正它。是 bash 去掉了额外的/s 还是真的无关紧要?

我问是因为它会为我节省几行代码来/在连接时检查额外的s。我知道这没什么大不了的,但我也很好奇。我有一个包含行cd //usr(而不是cd /usr)的 bash 脚本,这似乎暗示/在路径中使用多个s可能很重要

Gil*_*il' 191

允许使用多个斜杠,相当于一个斜杠。来自Single Unix 规范(版本 4)基本定义 §3.271 路径名:“多个连续的斜杠被认为与一个斜杠相同。”

有一个例外:如果路径名以两个连续的斜杠字符开头,则可以以实现定义的方式解释前导斜杠字符后面的第一个组件。(参考:基本定义 §4.13 路径名解析)。Linux 本身不会这样做,尽管某些应用程序可能会这样做,而其他 unix-ish 系统会这样做(例如 Cygwin)。

/路径名末尾的尾随强制路径名引用目录。在(POSIX 1003.1-2001(单一Unix V4)基本定义§4.11路径名解析,尾随/相当于尾部/.POSIX 1003.1-2008(单一Unix V4)基本定义§4.13去除了规定,使其相当于/.,为了处理不存在的目录(例如mkdir foo/,需要工作,而mkdir foo/.不会 - 请参阅更改的基本原理)。

对于作用于目录条目的程序,如果foo是指向目录的符号链接,则传递foo/是一种使程序作用于目录而不是符号链接的方法。

¹请注意,这仅适用于路径名解析,即访问文件时。文件名操作的工作方式可能不同。例如basenamedirname忽略尾部斜杠。

  • 与 `/.` 等价的内容在后来的讨论过程中被删除了,因为它是模棱两可的。无论如何+1,因为很难找到很好地总结的此类信息。 (9认同)

小智 17

操作系统似乎也不关心它,只是尝试了一个带有直接系统调用的 C 程序,以在路径中打开 //。

不过,您可以使用 python 库函数 os.path.normpath 对其进行规范化,这样您就不必扫描字符串以查找额外内容。其他语言也有类似的功能。

http://docs.python.org/library/os.path.html#os.path.normpath

  • 注意normpath的源码中的以下注释: Normalize a path,例如A//B、A/./B和A/foo/../B都变成了A/B。应该理解,如果它包含符号链接,这可能会改变路径的含义! (6认同)

Fre*_*Foo 10

在我见过的所有 Unix 系统上,它都与单个 相同/,但Unix 标准规定

以两个连续的斜杠开头的路径名可以以实现定义的方式解释,尽管两个以上的前导斜杠应被视为单个斜杠。

所以它可能会被特殊处理,具体取决于您的系统。(一些较旧的 Unix 版本使用双前导/进行远程文件系统访问,并且可能仍然有一些这样做。)

  • Cygwin(虽然不是真正的 UNIX)确实将 `//remote/...` 转换为远程文件系统访问,可能是为了与 Windows 的 `\\remote\...` 保持一致。 (9认同)
  • 我想我记得 Boost.Filesystem 的可移植路径名以特殊方式处理“//”,因为它们可以测试“false”是否是绝对的,符合 Unix/POSIX 规范。 (3认同)
  • 我相信(但现在不能在谷歌上搜索一个很好的参考)Windows POSIX 兼容 API 也会将 `//remote/...` 视为 UNC 路径 `\\remote\...` 格式。 (2认同)

Nei*_*hew 7

os.path.join在 Python 中使用,你不会得到多个斜杠。通过连接字符串自己构建文件名被认为是糟糕的 Python 风格。

  • @Falmarri:您不能只将文件名附加到命令字符串!命令字符串将由 shell 解析,因此文件名中的特殊字符需要用引号引起来。因此,您确实需要构造文件名,然后正确引用它以将其放入命令字符串中。 (2认同)
  • @Falmarri:所以使用normpath来清理你无法控制的命令行值,然后使用join将它们放在一起。 (2认同)