GNU 的手册页find
明确警告使用-delete
意味着-depth
.但是,我找不到对此要求的任何解释:
-delete
删除文件;如果删除成功则为 true。如果删除失败,则会发出错误消息。 [...] 使用-delete
自动打开该-depth
选项。
find --version
find (GNU findutils) 4.8.0
这隐式是后序行走:
find /path -type f -delete
但这是预序遍历,是 的常用遍历方法find
:
find /path -type f -exec rm -f {} +
如果我想用-prune
我就不能用-delete
,而必须使用更麻烦的-exec rm {} +
,但最终效果似乎是一样的。
该-delete
操作不会删除目录,那么为什么find -delete
需要暗示呢-depth
?
答案1
该
-delete
操作不会删除目录,那么为什么 find-delete
需要暗示呢-depth
?
对于 GNU 实用程序,参考文档是实用程序的信息文件,而不是其手册页;在某些情况下,问题中引用的手册页具有误导性。find -delete
可以删除目录:
删除文件或目录;如果删除成功则为 true。如果删除失败,则会发出错误消息。
-delete
find
自从2004 年在 GNU 中引入以来(findutils
4.2.3),它一直支持删除目录。
删除目录的原因是-delete
:-depth
它只能删除之前已清空的目录。-delete
在目录上相当于rmdir
, 而不是rm -rf
.
find /path -type f -delete
和的最终效果find /path -type f -exec rm -f {} +
是相同的,因为这两个find
调用都将其操作限制为文件。由于只删除文件,因此删除的顺序对find
的遍历没有影响。当删除目录时,find
的遍历确实会发挥作用。如果-delete
用于目录,则必须先处理目录的所有子目录,然后才能删除目录本身;这就是-depth
有用的地方。如果rm -rf
用于正在遍历的目录,则find
在尝试遍历已删除目录的子目录之前必须告知删除;这是-prune
有用的一个例子。
人们可以想象对其进行特殊处理,以便它不会设置-depth
是否不删除目录,但在一般情况下这是不可能提前确定的。 (-depth
是一个选项,而不是一个操作;它需要在实际处理第一个操作之前设置。)
或者,正如过去所提议的,我们可以想象根本不需要任何特殊处理-delete
,并让用户负责确保-delete
在必要时能够完成其工作。然而这会破坏向后兼容性以及与已复制的其他实现的兼容性-delete
。也可以看看Savannah bug #20865 中的讨论。
GNUfindutils
显式检查是否-delete
与-prune
从版本 4.3.11 开始,如果-depth
尚未明确设置则中止。评论指出
我们只能侥幸逃脱,因为该
-delete
谓词不在 POSIX 中。如果是的话,我们就不能在这里发出致命错误。
正如中所讨论的为什么使用 -delete 选项查找会删除我的 /save/ 目录中的文件,而不使用 delete 选项查找却无法找到它们?,如果您使用 GNU find
,则应该使用-execdir rm {} +
而不是-exec rm {} +
.