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

mel*_*yal 77 unix variables file path

将目录路径定义为变量或常量时,它是否应以尾部斜杠结尾?惯例是什么?

pwd在unix中显示当前目录没有尾部斜杠,而选项卡完成cd /var/www/apps/包括尾部斜杠,这让我不确定.

Dav*_*man 92

我使用尾随斜杠,因为:

  1. "如果它以斜杠结尾,那么它就是一个目录.如果不是,那就是一个文件." 是一个容易记住的常规.

  2. 至少在我经常使用的操作系统上,将斜线加倍会导致没有问题,而省略斜线会导致大斜杠.因此,最安全的做法是将斜杠放入变量并在使用它时使用"$ path/$ file".

  • 如果目录路径具有尾部斜杠,则目录路径仅可与文件路径区分开. (9认同)
  • 除非路径以双斜杠开头,否则多个斜杠相当于一个斜杠.见http://unix.stackexchange.com/questions/1910/how-linux-handles-multiple-path-separators-home-username-file (3认同)
  • 另外在vaariable末尾添加斜杠允许"$ path $ file"而不是"$ path/$ file",这允许空$ path - 表示当前工作目录.但绝不要使用反斜杠而不是斜杠. (3认同)
  • @Xtrinity 路径 `/stackoverflow.com` 与 `///stackoverflow.com` 相同,但与 `//stackoverflow.com` 不同。 (2认同)
  • 仅当目录路径尾部有斜杠和句点时,目录路径才能与文件路径区分开。单独的尾部斜杠代表目录中的所有文件。不是目录本身。 (2认同)
  • @TamusJRoyce 那么 `rmdir foo/` 会删除 `foo` 中的目录而不是 `foo` 本身?不,我不认为_“单独的尾部斜杠代表目录中的所有文件”_ 与常见用法或实用程序匹配。 (2认同)

Joh*_*erg 21

当我例如定义用于存储文件的目录时,我不包括尾部斜杠.那是因为我会喜欢它

$store_file = "$store_path/$file_id";
Run Code Online (Sandbox Code Playgroud)

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

  • 没有尾部斜杠意味着它不清楚$ store_path中的路径是文件还是目录."/ tmp/store_data"是文件还是目录? (26认同)
  • 在任何地方都有多个斜杠通常会被解释为单斜杠.所以你甚至可能有''///'+ $ root +'//'+ $ file +'/'`之类的东西,这没关系.虽然使用尾部斜杠是识别路径是文件还是目录的好方法,但最好是附加到`'/'+ $ root`而不是`$ root +'/'`之类的路径.你不能肯定被追加的路径有一个尾部斜杠,但你可以相对确信在大多数环境中多个斜杠将被解释为一个斜杠. (8认同)
  • 当使用PHP的[realpath()](http://php.net/manual/en/function.realpath.php)函数时,它不会打印尾部斜杠.您的系统和工具可能会规定您的惯例. (4认同)
  • 这个问题是:如果一个变量不存在,它就像空一样,`rm -rf $ foo/$ bar`可以以`rm -rf /`结尾 (4认同)
  • @Darwin:还有其他方法可以知道路径是否代表文件或目录。以 PHP 为例:is_file($path)、is_dir($path)。SplFileInfo 类(由 FileSystemIterator 类型对象生成)具有 $obj->IsDir()、$obj->IsFile() 方法;ETC。 (2认同)
  • @MatthewSlyman,我的意思是每个人都希望这个`/ tmp / store_data /`是一个目录,但不清楚`/ tmp / store_data`是什么路径而不加斜杠。 (2认同)
  • @12431234123412341234123 确实如此,但风险很低,因为现在大多数发行版都需要“--no-preserve-root”来造成严重损害。 (2认同)
  • @Darwin:我认为变量的名称应该表达这个含义,而不是它们的值 (2认同)

Pau*_*ams 9

是的它应该如下:

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

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

  • ..并没有考虑到它意味着你可能无意中弄乱了/,那种疯狂的谎言 (4认同)
  • 我不同意,因为字符串连接是文件系统路径的错误抽象。正如 [@Duncan 的回答](/sf/answers/4688647911/),使用 API 来获取路径。例如,C++ 的 `filesystem::path` 重载了 `operator/`,因此您可以执行 `pathname / filename`,或者在 Python 中执行 `os.join(pathname, filename)`。在具有变量插值的脚本语言中,您可以执行类似“$pathname/$filename”之类的操作(在组件之间显式添加目录分隔符)。依赖斜杠来使用非结构化字符串连接是非常脆弱的。 (2认同)

MrC*_*vin 7

我想这是极少数情况下正确的理论和实践答案不同的情况之一。

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

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

  • 最重要的原因是你可以确定路径/home/FSObjectX/是一个文件夹,但它/home/FSObjectX是不明确的。没有人能分辨这是一个文件还是文件夹。
    规格应尽可能准确且明确。

  • 在绝大多数情况下,您将始终引用文件夹的内容,而不是 dir 节点本身。
    在您实际执行的罕见情况下,可以通过删除任何可选的尾随目录分隔符在代码中轻松处理它。

  • 使用双目录分隔符不会造成任何损害,尽管缺少一个肯定会造成损害。
    从理论上讲,这是一个糟糕的论点,因为您不应该“偶然”编码,但实际上,错误会发生,并且也许使用尾随 dir-sep 可能最终会在最终用户处减少一些运行时错误。

通读这个有趣的线程,我没有发现使用 Trailing dir-sep 的任何缺点,只是它在理论上是错误的。或者我错过了什么?

  • 在实际实践中,您会发现正确的期望是不包含尾部斜杠。只需查看您使用的每个工具,这些工具都是由有能力的开发人员编写的。 (2认同)
  • 我理解你的推理,但是你不太可能对你的路径进行硬编码(如果你这样做,你会同时对路径和文件名进行硬编码)。如果我看到 `$homedir = "/home/FSObjectX";` 我就可以相当肯定它是一个目录。如果我感觉特别不信任,我可以要求文件系统来验证它。规范确实需要精确且明确,但在许多规范中,“/home/FSObjectX/”明确是对内容的引用,“/homeFSObjectX”明确是对节点的引用。花几个小时玩一下“rsync”才能真正理解其中的区别:) (2认同)

Bas*_*usa 6

在 php 中,由于 dirname(__FILE __) 函数返回目录名称,末尾不带斜杠。我倾向于坚持这个惯例。

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

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

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

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

  • 一个例外:dirname('/test')='/' — 在这种情况下,dirname 返回一个斜杠,而不是返回空字符串!请参阅[此处](http://php.net/manual/en/function.dirname.php)的注释。 (3认同)

jer*_*jvl 5

每当我存储目录路径或从API返回它们时,我都会尝试遵循保持尾部斜杠的惯例.这避免了整个'它是文件还是目录'的模糊性.

附录:
这并不是要替代使用能够容忍尾随斜线或缺席的方法.即使使用这种惯例,我仍然总是使用Path.Combine(...)和类似的方法.

  • python: `os.path.join(dir, subdir_or_file)` (2认同)

Dan*_*Man 5

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

现在,如果由于某种原因,当您连接字符串时缺少通向文件的路径,您最终会得到类似的东西/filename,它不仅是一个文件,而且是来自根目录的绝对路径(无论在该上下文中的任何位置) .

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

  • 这里的替代方法是将文件名表示为“./filename”。但一般来说,正确连接路径应该是代码的责任——而不是做出任何假设。 (3认同)

小智 5

我知道这是一个旧线程,但我想我会分享我所做的事情。如果可能的话,我通常会同时允许两者并执行类似的操作(如果是 PHP):

$fullPath = rtrim($directory, '/') . '/filename.txt');
Run Code Online (Sandbox Code Playgroud)

这样,如果目录是在配置文件中定义的,那么下一个更改它的人是否包含尾部斜杠并不重要。


Kar*_*bur 5

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

不,绝对不

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

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

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

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

值得指出的是,仅仅因为它是错误的,并不意味着工具/程序包/库就永远不会这样做。在这种情况下,如果不存在斜杠,则会在末尾添加斜杠,这是非常常见的情况。因此,正如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

  • 很好的答案。我倾向于使用这种方法,但从未完全完整地解释过原因。这是唯一能说明问题的答案。 (4认同)
  • 你*永远*不会*以`/.`结尾,这是一个糟糕的主意;除了注入非常不寻常的内容导致意想不到的麻烦之外,它看起来简直是愚蠢的。 (3认同)
  • 破坏模式的是根“ /”。而且,如果您要从此处开始(递归地)进行推理,那么您就可以了解可能是差异化实践的核心的矛盾(如此处答案所证明)。但是,一旦您将其作为例外,其他所有内容都将符合要求。 (2认同)
  • @wardw,您可以将根目录视为被命名为空字符串,而“/”是一个空字符串,后跟一个斜杠,表示“根目录的内容”。 (2认同)
  • 这个答案应该得到更多支持。另请参阅 Wiki 中的_[文件路径误解](https://en.wikipedia.org/wiki/Talk:Path_(computing)#Filepath_Misconceptions)_部分。 (2认同)
  • @bobpaul您可能会认为空字符串是根目录的名称,但如果您尝试通过空字符串(不带斜杠)引用根目录,则这种想法就会破裂:) (2认同)
  • 另外,我通过 CMake 意识到,当安装到权限不同的用户不拥有的目录时,带有尾部斜杠的路径会导致错误。另外,你所说的很有意义,所以后面没有斜杠。 (2认同)