使用 `find` 删除

使用 `find` 删除

因此,给出三个选择...

  1. find .... -delete
  2. find .... | xargs rm ...
  3. find .... -exec rm ...;

..或其变体,哪种选择更可取?
我猜没有硬性答案,具体情况将决定最佳选择(请说出它们!)

干杯。

答案1

选项 1 将避免产生外部进程,这在压力条件下很有用。

选项 2 将生成单个xargs进程,该进程将仅生成所需数量的rm进程。此选项通常与 和 一起使用,-print0-0处理带有空格和/或换行符的文件名。

选项 3 将为rm每个文件产生一个进程。

GNU find(或任何符合 POSIX 标准的 find 版本)允许第四个选项,find .... -exec rm -r {} +它将rm使用尽可能多的文件名运行以便仅生成有限数量的文件名。

答案2

我更喜欢find ... > file.txt广泛地使用审查文件,然后使用,find ... -delete这样我知道完全相同的结果将被删除(传递参数大多是无懈可击的,大多是)。

答案3

GNU findutils 文档中的“清理”部分介绍了删除文件的主题。您可以在系统上使用“info find”或在 Emacs 中阅读该文档。您也可以在线查看http://www.gnu.org/software/findutils/manual/html_node/find_html/Cleaning-Up.html#Cleaning-Up

find .... -delete

这是最安全(防止符号链接竞争)和高性能(因为当管道缓冲区已满时无需执行任何操作或执行上下文切换)的选项。但请记住 -delete 隐含 -depth。

find .... | xargs rm ...

如果其他人对您正在执行清理的树具有写访问权限,那么这种情况很危险。例如,假设 find 命令确定 /var/tmp/scratch/me/.ssh/config 符合其要求,因此将该名称打印到 stdout。xargs 命令将读取该文件并将其添加到数据结构中。不久之后(当 xargs 读取了 -s 选项的默认值指示的字节数时),xargs 将分叉并执行 rm 以删除它。但是,在此期间,其他人可能已经这样做了:

$ cd /var/tmp/scratch
$ mv me me.old
$ ln -s /root me

然后,当 rm 删除 /var/tmp/scratch/me/.ssh/config 时,它将发出系统调用 unlink("/var/tmp/scratch/me/.ssh/config")。由于内核将为您解析符号链接,因此这相当于它调用 unlink("/root/.ssh/config")。如果 xargs 进程以 root 身份运行,则 /root/.ssh/config 将被删除,尽管您没有在命令行上指定 -L。因此,如果安全性很重要,请使用 -delete。您可以在 GNU find 手册的“安全注意事项”部分中阅读有关此区域的更多信息。

find .... -exec rm ...;

因为这也涉及到 fork/exec,所以它具有我上面提到的相同的安全问题。

简而言之,不使用 -delete 的唯一原因是与缺乏对 -delete 支持的系统兼容。

相关内容