GNU find 使用 -exec rm 删除匹配项,然后抱怨它们不存在

GNU find 使用 -exec rm 删除匹配项,然后抱怨它们不存在

我有一个/domains目录,其中有如下条目

theawesomesite.com
0.2.v.theawesomesite.com
0.3.v.theawesomesite.com

测试完 0.3 版后,我会将主域设置为新版本的别名。效果非常好。现在,我希望能够删除所有旧版本。我尝试了以下方法:

find /domains -name "*.v.theawesomesite.com" -not -name "0.3.v.*" -ignore_readdir_race -exec rm -fr {} \;

旧的域目录被删除了,但每个目录都find抱怨No such file or directory。我添加了它,-ignore_readdir_race认为它会有所帮助,但事实并非如此。

有什么想法可以消除这些投诉,以及为什么find首先要投诉。它必须stat在之后-exec,但我不知道为什么。

答案1

尝试添加-depth标志,在目录本身之前处理每个目录的内容。

提问者编辑:或者,-prune 标志,因为我根本不关心内容。您的建议让我想到在删除目录后搜索目录,这是我没有考虑到的,并给了我最终答案,所以我想让这个成为我实际使用的正确答案。

答案2

您可以使用-delete动作来代替-exec(只要您有最近的发现)。

答案3

Find 最适合在需要递归目录时使用,但你似乎并不需要这样做。在这种情况下,我只需要做一些 shell 魔术。选项包括:

for dir in *.v.theawesomesite.com
    [[ $dir == 0.3.v.theawesomesite.com ]] || rm -r $dir
done

或者:

echo *.v.theawesomesite.com | grep -v '^0.3.v.theawesomesite.com$' | xargs rm -r

甚至:

mv 0.3.v.theawesomesite.com 0.3.v.theawesomesite.com.SAVED
rm -r *.v.theawesomesite.com
mv 0.3.v.theawesomesite.com.SAVED 0.3.v.theawesomesite.com

答案4

尝试使用单引号而不是双引号。

shell 在将双引号传递给 之前会将其扩展find,因此它可能在文件之前先 rm 目录:

find /domains -name 0.2.v.theawesomesite.com 0.2.v.theawesomesite.com/file1 ...

因此它可能先处理目录,然后查找刚刚删除的文件。

相关内容