为什么'find -delete'递归地删除目录中的所有文件


15

因此,unix的以下发现行为使我付出了巨大的代价:

> touch foo
> touch bar
> ls  
bar  foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar  baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?

这有什么意义?


2
这个问题是相关的,可能对以后的读者很有趣。unix.stackexchange.com/questions/101282/…–
Bernhard

Answers:


14

find的命令行由不同类型的选项组成,这些选项组合在一起构成了表达式。

find选项-delete是一个动作。
这意味着将对迄今为止匹配的每个文件执行该命令。
作为路径后的第一个选项,所有文件都将匹配...糟糕!

这很危险-手册页至少有一个警告

来自man find

ACTIONS
    -delete
           Delete  files; true if removal succeeded.  If the removal failed, an
           error message is issued.  If -delete fails, find's exit status  will
           be nonzero (when it eventually exits).  Use of -delete automatically
           turns on the -depth option.

           Warnings: Don't forget that the find command line is evaluated as an
           expression,  so  putting  -delete first will make find try to delete
           everything below the starting points you specified.  When testing  a
           find  command  line  that  you later intend to use with -delete, you
           should explicitly specify -depth in order to avoid later  surprises.
           Because  -delete  implies -depth, you cannot usefully use -prune and
           -delete together.


从更深处开始man find

EXPRESSIONS
    The expression is made up of options (which affect overall operation rather
    than  the  processing  of  a  specific file, and always return true), tests
    (which return a true or false value), and actions (which have side  effects
    and  return  a  true  or false value), all separated by operators.  -and is
    assumed where the operator is omitted.

    If the expression contains no actions other than  -prune,  -print  is  per‐
    formed on all files for which the expression is true.


在尝试find命令将执行的操作时:

看看命令是什么样的

find . -name '*ar' -delete

将被删除,您可以先将其替换-delete为更无害的操作- -fls-print

find . -name '*ar' -print

这将打印受操作影响的文件。
在此示例中,-print可以省略。在这种情况下,根本没有动作,因此最明显的是隐式添加:-print。(请参见上面引用的“表达式”部分的第二段)


我想我只是不读手册第一白痴。但它似乎如此直白地只需添加-delete标志:-)但没有任何人会做的原因find . -delete,而不是rm -rf .?还是恰好是find解析和处理其参数的方式?
mszep

1
哦,我完全同意语法非常危险 -但这是很难避免的,因为这只是find的命令行表达式语法的特例,它非常强大。功能强大,如“ 强大的电锯 ”。
Volker Siegel 2014年

引用的手册页warning: use -depth when testing stuff you later want to -delete上没有说明您在实际示例中没有做过的事情吗?
pqnet 2014年

哦,对了-问题是标题-我的意思是说明在-n选项-delete的位置使用print ;当然,第一个命令根本不应该有任何实际用途。我去改变它。
Volker Siegel

9

find论据顺序上很重要。

参数可以是选项,测试和操作。通常,您应该首先使用选项,然后进行测试,然后再进行操作。

有时find甚至会警告您可能存在错误的排序(例如,当您-maxdepth在其他参数后面使用时),但其他情况似乎并非如此。

什么find . -delete -name '*ar'是:

  1. 在当前目录下查找文件和目录。
  2. 找到它们后将其全部删除!
  3. 然后查看它们是否被命名为“ * ar”(此部分现在无效)。

您可能想做的是:

find -name '*ar' -delete

对于每个文件,这将查看其是否匹配'*ar',并且仅在满足条件时才会删除该文件。

对不起,如果发现太晚了。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.