使用 find 删除文件夹 - 奇怪的消息

使用 find 删除文件夹 - 奇怪的消息
mkdir foodir
find . -iname foodir -exec rm -fr {} \;

它完成了工作,但吐出消息:

find: `./foodir': No such file or directory

答案1

事件的确切顺序会是这样的

  1. 创造foodir
  2. 发射find
    1. find 读取当前目录,缓存结果,然后迭代它,找到 foodir 的条目
    2. find 启动execfoodir 命令,删除 foodir
    3. find 尝试递归到 foodir (它在 find 的内部缓存中),该缓存已不存在
    4. find 显示一条警告,表明无法递归到 foodir
    5. find 继续处理下一个条目(在这种情况下可能是目录条目列表的末尾,因此它在尽其所能完成其工作后退出)

因此,你所看到的情况是完全可以解释的,尽管从外部角度来看有些出乎意料。

几乎可以肯定,进行缓存是为了提高性能,为每个文件节省大量潜在的系统调用以及相当多的潜在磁盘 I/O。如果没有事务性文件系统(这是常见但不能保证的),即使 find 确实为每个条目读取一次目录,也不能保证您不会遇到这样的问题;特别是在非本地文件系统的情况下,甚至命令条目的数量可能在检查之间发生变化,因此您也不能简单地跟踪索引,而必须跟踪您访问过的每个目录条目。对于大型目录层次结构,这很快就会变得令人望而却步。

一般来说,这被称为“竞争条件":计算的前提条件在计算完成和使用结果值之间发生变化。

查看 GNU find 的手册页,有一个选项-ignore_readdir_race可能有助于抑制警告。但是,我不知道这对于通过 find 执行的任何其他命令有多大作用。根据您的需求,这可能就足够了。您还可以通过将其标准错误重定向到 /dev/null (附加2>/dev/null到命令行)来抑制 find 中的任何错误和警告,但我不建议这样做,因为它可以隐藏更严重的错误。我也不知道这将如何与调用的命令的任何错误输出交互。

答案2

find在启动时统计目标目录以获取目录的内容。然后,它处理您给它的命令,在本例中,它通过删除条目来更改目录的内容。因此,find该目录包含的内容的想法与现实不一致,并且它发出警告消息。

答案3

这似乎是有道理的 - 你的命令找到 foodir 然后将其删除。命令的顺序是消息的原因。

答案4

请改用此命令

find . -iname foodir | xargs rm -Rf

相关内容