为什么 `cp` 和 `rm` 分别对待目录?

为什么 `cp` 和 `rm` 分别对待目录?

为什么工具喜欢cprm目录与常规文件分开处理?它们都要求用户明确指定她想要递归行为,否则它们根本不会处理目录。

我与计算机的第一次交互(不久前)是在 Windows/GUI/点击/拖放环境中,无论目标如何,这些操作的行为都是相同的,这似乎总是很自然的。

当我使用通配符发出命令时,这种行为尤其让我感到沮丧。如果我想删除目录 ( *) 中除以下内容之外的所有内容该怎么办非空子目录

我只能想象这是某种安全功能,以防止用户搬起石头砸自己的脚,但这与我对一些 Unix 原则的理解相矛盾:

  • Unix 通常不会保护用户免受自身侵害。它始终假设用户知道她在做什么。
  • 对于 Unix 来说一切都是文件。目录不就是另一个文件吗?为什么他们受到不同的对待?

我的问题:

  • 这种行为是源于技术限制还是故意的选择?

如果是后者,

  • 历史上有没有关于促使这一选择的原因的记载?

答案1

德罗伯特的为什么 unix mv 程序不需要目录的 -R (递归)选项,但 cp 需要它?基本上回答了您的问题:复制或删除常规文件与对目录执行相同的操作不同,因为对于目录,您必须处理其中包含的所有文件。因此,操作是根本不同的。

另外值得注意的是,有一个特殊的实用程序rmdir只能作用于空目录。在不检查事实的情况下,这会导致人们得出结论,也许最初rm只能删除非目录,而深度删除必须通过递归地使用rm空目录然后rmdir删除这些目录来实现。

答案2

在某些 UNIX 版本中,rm 的手册页将其指定为取消文件链接的命令。
在 UNIX 中,文件是文件系统中称为索引节点的对象,除了文件系统中的 ID 之外没有名称或位置。它们的名称是对各个目录中它们的引用,目录是一种文件类型,对其中列出的文件(或目录,因为它们是文件)进行索引。
当取消链接文件时,文件的引用计数会减少,当它达到 0 时,它实际上被删除,因为它被文件系统标记为空闲,并且它的块/范围也被标记为空闲。

如果您能够在不先取消链接其中的文件的情况下管理一个目录,那么您将达到文件系统中引用了索引节点但无法通过任何正常方式访问的程度。
由于根据引用计数对它们进行了引用,因此它们不会被标记为已删除并成为丢失的文件。
当丢失的“文件”是目录时,情况会变得更加复杂,因此会增加文件系统中丢失的存储量。

因此,添加了 rm -r,作为一项减轻 UNIX 用户生活的功能,但以牺牲标准的“UNIX 精神”为代价,因为它比经典的 UNIX 实用程序更复杂,因为它会下降到目录并删除其中的文件,

另外,在UNIX早期,系统没有大量的内存,映射目录的递归结构确实会带来性能损失,有时如果不拆分工作就无法完成。

cp,读取文件并逐块复制它。如果要像复制文件一样复制目录,它会在不增加引用计数的情况下添加对其中文件的引用,这可能会导致数据不一致(如果读取/写入其块标记为空闲的 inode,因为它们的块被标记为空闲)。原始索引节点已被删除),丢失数据 - 因为删除对文件的最后一个(已知)引用可能会导致其索引节点号被回收。

对于 tl;dr 人群:
UNIX 中的目录是一种文件类型,这是事实,但由于系统对其中的信息进行了不同的处理,因为它是文件系统的元数据,因此操作文件的命令无法在目录上运行,除非更改其操作行为。以及依赖元数据。

相关内容