因此,给出三个选择...
find .... -delete
find .... | xargs rm ...
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 支持的系统兼容。