目录路径变量是否应以斜杠结尾?


85

在将目录路径定义为变量或常量时,它应该以斜杠结尾吗?有什么约定?

pwd在Unix中,显示的当前目录没有斜杠,而完整的制表符cd /var/www/apps/包括斜杠,这让我不确定。

Answers:


23

例如,当我定义用于存储文件的目录时,我不包括斜杠。那是因为我会像

$store_file = "$store_path/$file_id";

在使用应该保存目录路径的变量之前,我将始终添加一个斜杠。我认为总要添加一个总比不知道是否包含尾部的斜线更好。


29
如果没有斜杠,则表示不清楚$ store_path中的路径是文件还是目录。“ / tmp / store_data”是文件还是目录?
达尔文

4
当使用类似PHP的realpath()函数的东西时,它将不会打印出斜杠。您的系统和工具可能会决定您的约定。
jmbertucci 2012年

10
通常在任何地方具有多个斜杠将被解释为单个斜杠。因此,您甚至可以拥有类似的东西'///' + $root + '//' + $file + '/',这无关紧要。尽管使用斜杠是辨别路径是文件还是目录的好方法,但最好将路径附加到类似之类,'/' + $root而不是$root + '/'因为不能肯定要附加的路径是否带有斜杠,但您可以相对放心,在大多数环境中,多个斜杠将被解释为单个斜杠。
Xtrinity

3
@MatthewSlyman,我的意思是每个人都希望这 /tmp/store_data/是一个目录,但不清楚在没有斜线的情况下是什么相同的路径/tmp/store_data
达尔文,

6
问题是:如果变量不存在,则等于空,并且rm -rf $foo/$bar罐可以以rm -rf /
124312341234123412341234

100

我用斜杠结尾是因为:

  1. “如果以斜杠结尾,则为目录。如果不是,则为文件。” 是一个容易记住的约定。

  2. 至少在我通常使用的操作系统上,将斜杠加倍不会造成任何问题,而省略斜杠会造成较大的问题。因此,将斜杠放入变量中并在使用时使用“ $ path / $ file”是最安全的。


9
如果目录路径带有斜杠,则只能将其与文件路径区分开。
达尔文

4
除非路径以双斜杠开头,否则多个斜杠等效于一个斜杠。参见unix.stackexchange.com/questions/1910/…– jdh8 2013
20:42

4
另外,在vaariable的末尾添加斜杠允许使用“ $ path $ file”而不是“ $ path / $ file”,从而允许使用空$ path-表示当前工作目录。但切勿使用反斜杠代替斜杠。
fantastory 2015年

文件描述符也很有用
Francesco Gualazzi 2015年

@ jdh8即使路径以双斜杠开头,也应等效于一个斜杠。尽管这可能会因实施方式而有所不同。Unix标准指出,A pathname that begins with two successive slashes may be interpreted in an implementation-defined manner, although more than two leading slashes shall be treated as a single slash.在大多数情况下,通常在公共实现中双斜杠通常被解释为单斜杠。
Xtrinity

11

我知道这已经有10年的历史了,但我想投入我自己的0.02美元。

不,绝对不

我们正在谈论Unix系统。关于目录本身,它是一个节点,就像其他节点一样。当提到的目录,它不应该曾经有在其名称中的转义斜杠(参考:dirnamepwd~echo $HOMEecho $PATH,从输出ls等)。

当引用目录的内容时,需要一个斜杠。也就是说,ls /home/karl/它比ls /home/karl(FTR,我几乎总是这样做,因为...好吧,懒惰)更合适。

当使用包含目录的变量来创建文件的完整路径时,您总是希望包含斜杠(即:)cp ${HOME}/test ${OTHER_DIR}/

预计,一个目录不是在一个斜线结束。对目录以斜杠结尾的任何期望都是错误的。因此,在*_DIR变量值的末尾添加斜杠将破坏预期。

至于制表符补全,这里的期望是您要进入该目录。因此,制表符补全提供的帮助是使您进入该目录,以便您可以基于目录的内容进行下一个选择。

(来自注释的参考:Filepath Misconceptions,来自Wikipedia的Talk:Path_(computing)页面。谢谢john cj

值得注意的是,仅仅因为它是错误的,并不意味着工具/软件包/库永远都不会这样做。很少有这样的事情在不存在斜杠的情况下加一个斜杠,这是非常常见的情况。因此,正如BevanPaul F都建议的那样,在使用第三方工具时,最好删除目录名称中可能存在的任何斜杠。

Unix索引节点

索引节点(索引节点)是Unix样式的文件系统中的数据结构,用于描述文件系统对象(例如文件或目录)。

- https://en.wikipedia.org/wiki/Inode

文件系统层次结构标准

对Unix文件系统(文件系统层次标准,AKA FHS)标准清楚地表明,目录不会认为具有尾随斜线,而是目录的内容开始以斜线(唯一的例外是/,因为我们将不参考通过使用一个空字符串来作为文件系统根目录...并且无论如何都不应在其中创建文件。)

- http://www.pathname.com/fhs/pub/fhs-2.3.html

- https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard


极好的答案。我倾向于使用这种方法,但是对于我的推理却从未完全完成。这是唯一的答案。
wardw

4
/是打破模式的根源。而且,如果您要从此处开始(递归)推理,那么您就可以了解可能是差异化实践的核心的矛盾(如此处答案所证明)。但是,一旦您接受此例外,其他所有内容都将生效。
wardw

我懂了。玩了一点dirname。如果要在路径中显式存储目录,请在路径末尾添加“ /。”,其中的点代表当前目录。
塔穆斯·罗伊斯(TamusJRoyce)

永远不会以a结尾/.,这只是一个糟糕的主意;除了注入会导致意外麻烦的异常内容外,它看起来也很愚蠢。
卡尔·威尔伯

2
@wardw可以认为根目录被命名为空字符串,而“ /”是一个空字符串,后跟一个斜杠,表示“根目录的内容”。
bobpaul

9

是的,它应该为:

路径名+文件名=完全限定的文件位置。

因此,最后一个目录和文件名之间的斜线必须位于路径名的末尾或文件名的开头。用/前缀文件名意味着如果您只想打开文件(即,假设当前工作目录中存在不合格的文件名),则需要考虑这一点。


5
..并没有考虑到它,这意味着您可能无意间
弄到

5

每当我存储目录路径或从API返回目录路径时,我都会坚持遵循斜杠的惯例。这避免了整个“是文件还是目录”的歧义。

附录
不能替代使用可以容忍斜杠或斜杠不存在的方法。即使使用此约定,我仍然始终使用Path.Combine(...)和类似的方法。


python:os.path.join(dir, subdir_or_file)
IceArdor

5

也许您应该考虑您的决定对文件意味着什么。如果您没有在目录名的末尾添加斜杠,则必须将其添加到文件名的开头。

现在,如果由于某种原因,在连接字符串时缺少指向该文件的路径,那么您最终会得到这样的结果:/filename它不仅是文件,而且是根目录的绝对路径(无论在那种情况下都可以) 。

这就是为什么我用斜杠结束路径并将文件保留为文件的原因。


1
这里的替代方法是将文件名表示为./filename。但是总的来说,应该由代码负责将路径正确连接起来,而不是做任何假设。
wardw

4

我知道这是一个老话题,但我想我会分享我的工作。如果可能的话,我通常会同时允许两者,并做类似的事情(如果是PHP):

$fullPath = rtrim($directory, '/') . '/filename.txt');

这样,如果目录是在配置文件中定义的,则下一个要更改目录的人是否在后面加上斜杠都没关系。


4

在php中,由于dirname(__ FILE __)函数返回的目录名末尾没有斜杠。我倾向于遵守那个约定。

否则,在目录名的末尾使用斜杠将与dirname(..)的工作方式冲突,然后您将不得不处理这两种情况,因为您不知道目录名是否来自dirname(.. )功能或以斜杠定义的内容。

底线:不要使用斜线,因为dirname(..)不需要。

// PHP Example
dirname(__FILE__); // returns c:\my\directory without a trailing slash, so stick to it!

对于其他语言,请检查提取路径名的函数,并查看其是否使用斜杠,然后遵循该语言的约定。


2
例外:dirname('/ test')='/'-在这种情况下,dirname不会返回空字符串,而是返回单个斜杠!请参阅此处的注释。
马修·史莱曼


2

是的,有很多文件系统支持不带任何扩展名的文件,因此请始终添加斜杠以避免任何问题。


1

我从未见过任何一种坚定的约定。

但是,可以肯定的是,无论您选择哪种解决方案,其他人都会百分百确定应该采用其他方式。因此,最好的主意是容忍以任何一种方式设置的事物。

在.NET世界中,Path.Combine()提供了一种处理此问题的方法-从cmd文件开始,其他环境中也存在等效项。


1

我猜这是在少数情况下正确的理论和实践答案都不相同的情况之一。

从理论上来说,@ Karl Wilbur的答案似乎肯定是正确的,因为您应该能够将对目录节点本身的引用与目录的内容区分开。

但是在实践中,我认为正确的答案是相反的:

  • 最重要的原因是可以确定路径/home/FSObjectX/是文件夹,而路径/home/FSObjectX是模棱两可的。没有人知道这是否是文件夹文件。
    规格应始终是精确且明确的。

  • 在大多数情况下,您将始终引用文件夹的内容,而不是dir节点本身。
    在实际情况很少见的情况下,可以通过删除任何可选的结尾dir分隔符在代码中轻松地对其进行处理。

  • 使用双目录分隔符不会有任何危害,尽管可以肯定会丢失。
    从理论上讲,这是一个错误的论点,因为您不应该通过“机会”进行编码,但是在实践中,会发生错误,并且也许使用结尾dir-sep可能最终会减少最终用户的运行时错误。

通过阅读这个有趣的线程,我没有发现使用结尾dir-sep的任何缺点,只是从理论上讲这是错误的。还是我错过了什么?


在实际实践中,您会发现正确的期望是不要包含斜杠。只要看看您使用的所有由有能力的开发人员编写的工具即可。
卡尔·威尔伯
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.