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


111

我正在研究将文件位置传递给scp子进程的python脚本。没关系,但是我遇到的情况是我可能最终将路径与文件名连接起来,使得路径中有一个double' /。我知道bash不在乎您是否有多个文件分隔符,但是我想知道如何更正此问题。是bash去除多余的/s还是真的没有关系?

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


7
我会投资额外的代码行...
Stefan 2010年

5
万一有人关心,我敢肯定,没有人做,我做实际上最终使用Python joinabspath和这样的命令。
Falmarri

Answers:


165

允许使用多个斜杠,并且等效于单个斜杠。从Single Unix规范(版本3)开始基本定义§3.266路径名:“多个连续的斜杠被认为与一个斜杠相同。”

有一个例外:如果路径名正好以两个斜杠开头,则可能会被区别对待(请参阅基本定义§4.11路径名解析)。Linux本身不这样做,尽管某些应用程序可能会这样做,而其他unix-ish系统也会这样做(例如Cygwin)。

/路径名末尾的尾部将强制该路径名引用目录。在(POSIX 1003.1-2001(单一Unix v3)的基本定义§4.11路径名解析,尾随/相当于尾部/.POSIX 1003.1-2008(单一Unix V4)基本定义§4.12去除的要求,使之等同于/.,为了来应对不存在的目录(例如mkdir foo/,需要工作,而mkdir foo/.不会—参见更改的理由)。

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

¹ 请注意,这仅适用于路径名解析,即在访问文件时。文件名操作可能会有所不同。例如basenamedirname忽略斜杠。


7
由于/.模棱两可,因此在以后的讨论过程中已删除了等效项。无论如何+1是很难找到这样的信息的总结。
hakre 2014年

17

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

不过,您可以使用python库函数os.path.normpath对其进行标准化,从而省去了遍历字符串以查找其他内容的麻烦。其他语言具有类似的功能。

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


5
当心normpath的源代码中的以下注释:标准化路径,例如A // B,A /./ B和A / foo /../ B都变为A / B。应该理解,如果路径包含符号链接,则可能会更改路径的含义!
Bluehorn 2014年

8

在我所看到的所有Unix系统上,它都与单个相同/,但是Unix标准规定:

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

因此可能会根据您的系统进行特殊处理。(某些较早的Unix版本使用双引号/进行远程文件系统访问,并且可能仍然有一些这样做。)


7
Cygwin(虽然不是真正的UNIX)确实转换//remote/...为远程文件系统访问,可能是为了与Windows保持一致\\remote\...
短暂的2011年

2
我相信(但现在无法在Google上找到很好的参考)Windows POSIX兼容API也将//remote/...与UNC路径\\remote\...格式相同。
斯蒂芬·P

1
我想我记得,Boost.Filesystem的可移植路径名//以一种特殊的方式处理,因为它们可以测试false是否是绝对的,符合Unix / POSIX规范。

7

os.path.join在Python中使用时,不会出现多个斜线。通过串联字符串自己建立文件名被认为是不良的Python风格。


我同意,但是文件名是命令字符串的一部分,而不是解析命令字符串以附加到文件名(最后),我只是想附加它。
Falmarri 2010年

1
@Falmarri:您不能仅将文件名附加到命令字符串!外壳程序将解析命令字符串,因此需要在文件名中加上特殊字符。因此,您确实需要构造文件名,然后正确引用它以将其放入命令字符串中。
吉尔斯(Gilles)2010年

这是一个非常具体的项目,我几乎将要使用我自己。我可能还不够清楚,不能证明对此不足够强健。我从一个类中获取此文件路径字符串,该类为我提供了正确转义的文件路径等。我将其附加到命令行参数中
Falmarri 2010年

1
@Falmarri:因此,请使用normpath清理您不控制的命令行值,然后使用join将它们放在一起。
尼尔·梅休

实际上,这就是我最终要做的事情。\\我无法很好地处理我得到的特殊情况/
Falmarri

3

没有区别。

多个斜杠将被忽略(不起作用),例如:

ls -al //usr///////bin/sed

7
可能是,如果它正是两开头; 以两个连续的斜杠开头的路径名可以以实现定义的方式解释。实际上,我认为这是对的,他们只会被忽略
Michael Mrozek

谢谢克里斯,我感谢您的澄清!(不幸的是,OpenID登录对我不起作用,否则我会投票赞成)

@Rob您尚未注册,但仍已登录(通过Cookie进行跟踪)。您现在应该可以注册以将OpenID连接到您的帐户,但是您应该能够以任何一种方式进行投票
Michael Mrozek

感谢Michael,但“您必须登录或注册才能投票”。仅使用电子邮件地址和名称时,您没有完整的权限。而且由于OpenID超时,而且我不想创建另一个帐户,所以我很不走运。我猜是我懒惰的错,但我感谢您的帮助。

0

当然,您可以通过传递路径来规范化其中可能带有多个/(斜杠)的路径 tr -s

NORMALIZED=$(echo "$UNHYGIENIC" | tr -s / /)

...然后使用 $NORMALIZED

但是,这是必要的。据我所知,任何适当的UNIX内核都应忽略并发路径分隔符---或在概念上将它们视为... /./...


“应该”->“不应该”。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.