我正在研究将文件位置传递到scp子进程的python脚本。没关系,但是我遇到的情况是我可能最终将路径与文件名连接起来,使得路径中有一个双'/。我知道bash不在乎您是否有多个文件分隔符,但是我想知道如何正确地对其进行纠正。是bash剥离了额外的/还是真的没关系?

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

评论

我会投资额外的代码行...

万一有人在乎,我确定没有人在乎,我最终使用的是python join和abspath等命令。

#1 楼

允许使用多个斜杠,并且等效于单个斜杠。从Single Unix规范(版本4)开始,基本定义§3.271路径名:“多个连续的斜杠被认为与一个斜杠相同。”
有一个例外:如果路径名以两个连续的斜杠字符开头,前面的斜杠字符后的第一个组件可以以实现定义的方式进行解释。 (参考:基本定义§4.13路径名解析)。 Linux本身不这样做,尽管某些应用程序可能会这样做,而其他unix-ish系统也会这样做(例如Cygwin)。
路径名结尾的结尾/会强制该路径名引用目录。在(POSIX 1003.1-2001(Single Unix v4)基本定义§4.11路径名解析中,尾随/等同于尾随/. .POSIX 1003.1-2008(Single Unix v4)基本定义§4.13删除了使其等同于/.的要求,以便处理不存在的目录(例如,需要mkdir foo/才能工作,而mkdir foo/.则不能工作(请参阅更改的原理)。
对于作用于目录条目的程序,如果foo是符号
¹请注意,这仅适用于路径名解析,即,在访问文件时,文件名操作可能会有所不同。例如,foo/basename忽略尾部斜杠。

评论


相当于/。由于模棱两可,因此在以后的讨论过程中已将其删除。无论如何+1是很难找到这类信息的摘要。

– hakre
2014年7月26日12:03



另请参见:// foo / bar在什么系统上与/ foo / bar不同?

–StéphaneChazelas
20-10-5在8:27

#2 楼

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

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

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

评论


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

–蓝角牛
2014年11月17日20:36



#3 楼

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


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


因此可以处理特别是,取决于您的系统。 (某些较早的Unix版本使用双前导/进行远程文件系统访问,并且可能仍然有某些功能。)

评论


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

–短暂
2011年1月20日,0:33

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

– Stephen P
2011年1月20日,0:39

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

–拉尔曼斯
2011年1月20日,0:52

#4 楼

在Python中使用os.path.join,不会出现多个斜线。通过连接字符串自己建立文件名被认为是较差的Python样式。

评论


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

–法尔玛里
2010-09-13的1:02

@Falmarri:您不能仅将文件名附加到命令字符串! Shell将解析命令字符串,因此需要在文件名中加上特殊字符。因此,您确实需要构造文件名,然后正确引用它以将其放入命令字符串中。

–吉尔斯'所以-不再是邪恶的'
2010-09-13在7:19

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

–法尔玛里
2010-09-13 7:38

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

–尼尔·梅休(Neil Mayhew)
2010-09-20 15:49

这实际上是我最终要做的= \我不能很好地处理我刚刚得到的特殊情况。

–法尔玛里
2010-09-20 17:44

#5 楼

没有区别。

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

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


评论


如果正好是两个,并且一开始可能存在。可以以实现定义的方式解释以两个连续的斜杠开头的路径名。实际上,我认为这是对的,他们只是被忽略了

– Michael Mrozek
2011年1月20日,0:22

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

–Rob
2011年1月20日,0:23

@Rob您尚未注册,但仍已登录(通过Cookie进行跟踪)。您现在应该可以注册以将OpenID连接到您的帐户,但是无论哪种方式都可以投票

– Michael Mrozek
2011年1月20日,0:28

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

–Rob
2011年1月20日,0:35

#6 楼

当然,您可以通过将路径传递给tr -s
NORMALIZED=$(echo "$UNHYGIENIC" | tr -s / /)

...然后再使用$NORMALIZED
来规范路径中可能带有多个/(斜杠)的路径,但这不是必须的。据我所知,任何适当的UNIX内核都应忽略并发路径分隔符---或从概念上将它们视为... /./ ...