什么时候应该在目录上使用尾部斜杠?

Cor*_*ein 71 directory slash filenames

可能的重复:
linux 如何处理多个路径分隔符(/home////username//file)

我在 linux 中使用的大多数命令的行为都完全相同,无论我是否/在目录名称的末尾包含斜杠字符。

例如:

ls /home/cklein
ls /home/cklein/

cp foo bar
cp foo/ bar/
Run Code Online (Sandbox Code Playgroud)

这个尾部斜杠什么时候重要?尾部斜杠的语义是什么?

Kei*_*son 56

一个很好的例子是将文件移动到目录中:

mv some_file foo
Run Code Online (Sandbox Code Playgroud)

对比

mv some_file foo/
Run Code Online (Sandbox Code Playgroud)

如果foo不存在,第一个将重命名some_filefoo,而不是预期的foo/some_file; 第二个会抱怨,这就是你想要的。

如果foo确实存在但不是目录,则第一个可以破坏foo文件;再次,第二个会抱怨。

cp 提出了类似的问题。

在一些旧版本的 SunOS 上,我养成了附加 的习惯/.,因为系统实际上忽略/了文件名的尾随;例如,/etc/motd/将引用文件而不是错误。SunOS / Solaris 的更高版本似乎没有这个问题。


Ign*_*ams 41

完全依赖于工具。rm如果末尾有斜杠,则不会让您删除指向目录的符号链接,如果源文件规范末尾有斜杠,则 rsync 会做不同的事情。

  • **在使用 `rsync` 时要特别注意!!!** 尾部斜杠真的很重要。 (28认同)
  • 在大多数情况下,尾随的 `/` 表示“将其视为一个目录,如果它是一个,则取消引用符号链接,如果它不是一个目录,则抱怨”。POSIX 指定的实用程序强制执行此行为。Rsync 的 source 参数是一个值得注意的例外。 (21认同)
  • @mathlehmann 很好的发现。开发人员想再聪明一点。让我们使用没有人记得如何使用的晦涩语法,而不是像日常一样清晰的附加选项(例如“--copy-unto”)。 (3认同)
  • 请注意,默认情况下,当目标是符号链接时,`chown -R /dir1/symlink1` 不会执行递归;然而,`chown -R /dir1/symlink1/` 会做你所期望的。 (2认同)
  • 尽管 OP 针对 Linux 提出了具体要求,但值得注意的是,所使用的操作系统或工具风格可能会有所不同。一个值得注意的例子是“cp”,当在 OS X (BSD cp) 和 Linux (GNU cp) 上使用“-r”选项时,它具有不同的行为。当使用 BSD cp 时,`cp -r src/ dest` 只会将 `src` 的内容复制到 `dest` 中,但当使用 GNU cp 时,会将目录 `src` 本身复制到 `dest` 中。(参见http://jondavidjohn.com/linux-vs-osx-the-cp-command/) (2认同)
  • @Wildcard是的,使用rsync,尾随的“/”对于*源*文件很重要。文件是否是远程的并不重要。 (2认同)

Sté*_*las 16

foo/就像foo/.,所以如果foo是一个目录的符号链接,foo/是一个目录(不是一个符号链接),如果foo不是一个目录或一个目录的符号链接,那么任何试图访问的东西都会得到一个 ENOTDIR 错误foo/。这就是 Linux 上的行为。

其他系统上的行为可能会有所不同。

请参阅此处此处以及此处以了解 POSIX/SUS 对此有何看法。

  • 谢谢。是的,令人烦恼的是,TC2 更新现在可以在与以前版本相同的 URL 上使用,但具有完全不同的 HTML 锚点。许多链接甚至都被破坏了,所以我希望它会再次改变。可能更好[链接到网络存档](https://web.archive.org/web/20110811062911/http://pubs.opengroup.org/onlinepubs/9699919799/xrat/V4_xbd_chap03.html#tag_21_03_00_59)来获取一致的链接。 (2认同)

Wil*_*ard 9

在 rsync 中,手册页内容如下:

   A trailing slash on the source changes this behavior to avoid  creating
   an  additional  directory level at the destination.  You can think of a
   trailing / on a source as meaning "copy the contents of this directory"
   as  opposed  to  "copy  the  directory  by name", but in both cases the
   attributes of the containing directory are transferred to the  contain-
   ing  directory on the destination.  In other words, each of the follow-
   ing commands copies the files in the same way, including their  setting
   of the attributes of /dest/foo:

          rsync -av /src/foo /dest
          rsync -av /src/foo/ /dest/foo
Run Code Online (Sandbox Code Playgroud)

目的地的尾部斜杠根本无关紧要。只在源头上。(然后,当然,仅当源是目录而不是单个文件或 glob 时才重要。)

为了说明目录到目录的用例:

$ mkdir foo bar baz
$ chmod 700 foo
$ chmod 750 bar
$ chmod 705 baz
$ echo hello > foo/file1
$ chmod 606 foo/file1 
$ ls -n
total 0
drwxr-x---  2 501  20   68 Aug  8 15:29 bar/
drwx---r-x  2 501  20   68 Aug  8 15:29 baz/
drwx------  3 501  20  102 Aug  8 15:30 foo/
$ ls -n foo
total 8
-rw----rw-  1 501  20  6 Aug  8 15:30 file1
$ rsync -a foo bar
$ rsync -a foo baz/
$ rsync -a foo bif
$ rsync -a foo bonk/
$ ls -n
total 0
drwxr-x---  3 501  20  102 Aug  8 15:30 bar/
drwx---r-x  3 501  20  102 Aug  8 15:30 baz/
drwxr-xr-x  3 501  20  102 Aug  8 15:30 bif/
drwxr-xr-x  3 501  20  102 Aug  8 15:30 bonk/
drwx------  3 501  20  102 Aug  8 15:30 foo/
$ ls -n *
bar:
total 0
drwx------  3 501  20  102 Aug  8 15:30 foo/

baz:
total 0
drwx------  3 501  20  102 Aug  8 15:30 foo/

bif:
total 0
drwx------  3 501  20  102 Aug  8 15:30 foo/

bonk:
total 0
drwx------  3 501  20  102 Aug  8 15:30 foo/

foo:
total 8
-rw----rw-  1 501  20  6 Aug  8 15:30 file1
$ rm -rf b*
$ mkdir bar baz
$ chmod 750 bar
$ chmod 705 baz
$ rsync -a foo/ bar
$ rsync -a foo/ baz/
$ rsync -a foo/ bif
$ rsync -a foo/ bonk/
$ ls -n
total 0
drwx------  3 501  20  102 Aug  8 15:30 bar/
drwx------  3 501  20  102 Aug  8 15:30 baz/
drwx------  3 501  20  102 Aug  8 15:30 bif/
drwx------  3 501  20  102 Aug  8 15:30 bonk/
drwx------  3 501  20  102 Aug  8 15:30 foo/
$ ls -n *
bar:
total 8
-rw----rw-  1 501  20  6 Aug  8 15:30 file1

baz:
total 8
-rw----rw-  1 501  20  6 Aug  8 15:30 file1

bif:
total 8
-rw----rw-  1 501  20  6 Aug  8 15:30 file1

bonk:
total 8
-rw----rw-  1 501  20  6 Aug  8 15:30 file1

foo:
total 8
-rw----rw-  1 501  20  6 Aug  8 15:30 file1
$ 
Run Code Online (Sandbox Code Playgroud)

  • +1。我一直在使用 `rsync`,并且已经使用了很多年,但我仍然无法记住 rsync 处理源目录尾随斜杠的确切细节。我**总是**必须先`--dry-run`它或阅读手册页。很高兴看到这个答案,但不太可能修复我的记忆:( (2认同)