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


10

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

我与计算机的第一次交互(前一段时间)是在Windows / GUI /指向和单击/拖放环境中,无论目标如何,这些操作的表现总是很自然的。

当我使用通配符命令时,这种行为使我特别沮丧。如果我想删除目录(*)中除非空子目录以外的所有内容,该怎么办?

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

  • Unix通常不会保护用户免受自己的伤害。一直假设用户知道她在做什么。
  • 对于Unix,所有内容都是文件。目录不只是另一个文件吗?为什么要区别对待他们?

我的问题:

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

如果是后者,

  • 是否有任何历史原因说明了这种选择的原因?

对于rm至少,如果你希望它忽略的文件和目录之间的差异,你可以把你的~/.bashrc文件:alias rm='rm -r'
BenjiWiebe

1
又见不同但相关的问题unix.stackexchange.com/questions/46066/...
derobert

1
您无法将cp和rm与Windows文件管理器进行比较。启动cmd.exe,然后尝试复制和删除并比较行为。
ott-- 2013年

Answers:


11

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

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


rmdir也是用于删除目录的系统调用的名称。对于系统调用,该目录必须为空,并且具有相同名称的实用程序仅是“前端”,类似于unlink命令和实用程序。
jordanm

确实-这就是让我相信最初rm可能根本无法删除目录的原因(因为命令行实用程序通常只是围绕syscall的相对简单的包装器)。
彼得

我的问题的标题可能会误导您以为我在询问技术细节。我问这是不是故意的选择。我想知道是否我是唯一认为从最终用户角度来看这种行为不一致的人。我接受您的回答,因为它间接地回答了我的问题:Unix内部(在系统调用级别)的技术限制似乎是这种行为的根源,而传统可能会阻止我们今天采取其他任何方式。难道“围绕syscall的简单包装器”应该给我们带来更多智能行为吗?
rahmu 2013年

2
从最终用户POV来看,确实确实很奇怪,但是您实际上是在询问原因。:)至于包装器-一切都取决于包装器的“简单”程度(以及您仍要称呼“简单”的东西)。Modern rm绝对不是简单的包装器(它能够立即删除mroe文件和目录)。如果您不喜欢-r使用该选项,请使用外壳的别名功能或创建自己的包装器以将其放置到位(虽然速度较慢,但​​与您使用的外壳无关)。
彼得

2

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

如果您有能力在不先取消链接目录的情况下对目录进行rm管理,则将达到在文件系统中引用了inode但无法通过任何常规方式进行访问的位置。
由于根据引用计数对它们进行引用,因此它们不会被标记为已删除并成为丢失的文件。
当丢失的“文件”是目录时,这变得更加复杂,因此增加了文件系统中潜在的丢失存储量。

因此,添加了rm -r以减轻UNIX用户的生命,该功能以标准的“ UNIX精神”为代价,因为它比传统的UNIX实用程序更复杂,因为它降级到目录并删除其中的文件,

另外,在UNIX的早期,系统没有太多的内存,并且映射目录的递归结构确实会降低性能,并且有时不分割工作是不可能的。

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

对于tl人群:
UNIX中的目录是一种文件,的确如此,但是由于其中的信息被系统以不同的方式对待(因为它是文件系统的元数据),所以在没有目录的情况下操作文件的命令将无法在目录中工作。改变他们的行为以操纵相关的元数据。

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.