mkdir foodir
find . -iname foodir -exec rm -fr {} \;
它完成了工作,但吐出消息:
find: `./foodir': No such file or directory
答案1
事件的确切顺序会是这样的
- 创造
foodir
- 发射
find
- find 读取当前目录,缓存结果,然后迭代它,找到 foodir 的条目
- find 启动
exec
foodir 命令,删除 foodir - find 尝试递归到 foodir (它在 find 的内部缓存中),该缓存已不存在
- find 显示一条警告,表明无法递归到 foodir
- 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