首页 > 解决方案 > find exec rm: 没有这样的文件或目录

问题描述

为什么在下面的示例中“没有这样的文件或目录”?有一些解决方法可以避免出现此错误,问题是为什么在这个确切的示例中会产生错误。

cd /tmp
mkdir -p TOP1/AB/AC/AD/AE/AF
mkdir -p TOP2/AB/AC/AD/AE/AF

find . -iname 'A*' -exec rm -rvf {} \;
removed directory: `./TOP1/AB/AC/AD/AE/AF'
removed directory: `./TOP1/AB/AC/AD/AE'
removed directory: `./TOP1/AB/AC/AD'
removed directory: `./TOP1/AB/AC'
removed directory: `./TOP1/AB'
find: `./TOP1/AB': No such file or directory
removed directory: `./TOP2/AB/AC/AD/AE/AF'
removed directory: `./TOP2/AB/AC/AD/AE'
removed directory: `./TOP2/AB/AC/AD'
removed directory: `./TOP2/AB/AC'
removed directory: `./TOP2/AB'
find: `./TOP2/AB': No such file or directory

使用-depth\+-delete修复此问题:

find .        -iname 'A*' -exec rm -rvf {} \+
find . -depth -iname 'A*' -exec rm -rvf {} \;
find . -iname 'A*' -delete

标签: linuxshell

解决方案


我认为答案在手册页本身:https ://linux.die.net/man/1/find

另请参阅\;vs +在 find 中使用分号 (;) vs plus (+) with exec

为了更好地了解整个过程,您可以打印文件而不是删除它们。以TOP1文件夹为例:

find . -iname 'A*' -exec echo "{}" \;

输出:

./TOP1/AB
./TOP1/AB/AC
./TOP1/AB/AC/AD
./TOP1/AB/AC/AD/AE
./TOP1/AB/AC/AD/AE/AF

作用是\;在当前目录中或之下的每个文件上运行文件。 顺序在这里很重要,即首先处理父文件夹,然后递归遍历其子文件夹。

另一方面,这是如何rm -frv工作的:

rm -frv ./TOP1

输出:

removed directory './TOP1/AB/AC/AD/AE/AF'
removed directory './TOP1/AB/AC/AD/AE'
removed directory './TOP1/AB/AC/AD'
removed directory './TOP1/AB/AC'
removed directory './TOP1/AB'
removed directory './TOP1'

所以rm -fr实际上与 相比find,这是问题的主要原因:

find\;first 一起从父文件夹开始,由于该部分TOP1,该文件夹TOP1及其内容将被完全删除-exec rm -rvf {} \;。在下一轮find然后将尝试处理下面的下一个子文件夹,它显然首先检查(通过stat ./TOP1),如果基本文件夹仍然存在,然后它只会更深一层。但是由于./TOP1在第一轮中已经被删除,stat ./TOP1会失败,因此出现错误消息。

使用其他可用的参数,find您显然可以更改默认行为:

  • -depth在(父)目录本身之前处理每个目录的内容。-delete 操作也意味着 -depth。(即从最底部到顶部摆动 - 就像rm -fr那样!)
  • -delete:使用 -delete 会自动开启-depth选项
  • 使用+:该-exec rm -rvf {} +部分仅执行一次,例如-exec rm -rvf {} +
rm -frv ./TOP1/AB ./TOP1/AB/AC ./TOP1/AB/AC/AD ./TOP1/AB/AC/AD/AE ./TOP1/AB/AC/AD/AE/AF

最后但同样重要的是:rm-fr参数一起使用时,它变得非常“宽容”,因此不会引发错误。它将尝试强制递归地删除传递给它的所有内容;而且,如果它遇到不存在的文件/目录,它也不会抱怨。


推荐阅读