在目录路径末尾包含 / 和省略它之间的区别

Ste*_*Fox 1 directory slash path

我只是想知道当我离开 / 在文件路径的末尾时会发生什么不同,例如:

root /var/www/website.com/
Run Code Online (Sandbox Code Playgroud)

并省略它,如:

root /var/www/website.com
Run Code Online (Sandbox Code Playgroud)

这是如何处理的或者有什么区别?

Ark*_*zyk 6

目录名称后面的斜杠在某些程序中很重要,而在其他程序中则不然。例如:

  • 在 git/文件名后仅表示目录而不是单个文件(来自man 5 gitignore):

    如果模式以斜杠结尾,则出于以下描述的目的将其删除,但它只会找到与目录的匹配项。换句话说, foo/ 将匹配目录 foo 和它下面的路径,但不会匹配常规文件或符号链接 foo (这与 pathspec 通常在 git 中的工作方式一致)。

  • ls(来自维基百科):


    请求指向目录的符号链接的目录列表时,将仅显示链接本身。在
    为了获得所链接的目录的列表,该路径必须
    包括一个尾随目录分隔符(“/”,斜线)。

  • 还有一些我现在不记得的其他程序(主要是我看到的 Emacs 宏),它们只需要一个目录而不是一个常规文件,它们将同时接受这两个文件dirdir//在需要时添加,例如引用dir.

我不知道 nginx 是如何工作的,但请参阅muru 的回答


fro*_*utz 6

一般来说,没有尾部斜杠的路径是不明确的:它可以是文件或目录。带有斜杠的路径只能是目录。大多数 shell 在使用制表符补全时会自动为您提供尾部斜杠。

这并不意味着您应该始终使用尾部斜杠;事实上,有些程序不允许使用它。正如其他人所说,这取决于上下文。每个程序对此都有不同的解释。

尾部斜杠产生巨大差异的一个例子是rsync.

给定目录sourcetarget,该命令rsync -a source target会将所有内容复制到target/source。但使用尾部斜杠,直接rsync -a source/ target将内容复制到source,而不创建子目录。targettarget/source

我经常对这种行为感到困惑,因此我更喜欢将其写出来,而不是依赖隐式子目录创建。有时我什至使用尾随/.来确保不会创建不需要的子目录,因为子目录.已经存在。


mur*_*uru 5

上下文真的很重要。For nginx,在root为一个位置指定 时,它没有任何区别,因为nginx知道它是一个目录。但是,它可能会在其他地方产生影响,因为双斜杠可能会导致 URL 出现问题(即,如果您blah/$request_uri在重写或代理时执行某些操作)。

一般来说,在 *nix 平台上没有区别。有一些例外:

  • rsync根据源目录路径是否具有尾部斜杠,行为会有所不同。rsync 如何处理尾部斜杠的一个很好的例子
  • 添加尾部斜杠可以让应用程序意识到它正在寻找一个目录,而不是意外创建一个文件:

    cp blah non-existent-directory
    cp blah non-existent-directory2/
    
    Run Code Online (Sandbox Code Playgroud)
  • 与上面类似,在 globbing 中,它只能用于强制扩展到目录:

    $ printf "%s\n" * | wc -l
    26
    $ printf "%s\n" */ | wc -l
    20
    
    Run Code Online (Sandbox Code Playgroud)

    原谅这个例子。它是在一个相当标准的 Ubuntu 安装的根目录上完成的,所以在这个例子的执行过程中没有损坏奇怪的名字。