为什么“find -delete”会递归删除目录中的所有文件

为什么“find -delete”会递归删除目录中的所有文件

因此,unix find 的以下行为让我付出了高昂的代价:

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

这有什么意义呢?

答案1

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。 (参见上面引用的“表达式”部分的第二段)

答案2

find论证中,顺序很重要。

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

有时find甚至会警告您可能存在错误的顺序(例如,当您-maxdepth在其他参数之后使用时),但其他人似乎没有。

所做find . -delete -name '*ar'的是:

  1. 在当前目录上查找文件和目录。
  2. 发现它们后将其全部删除!
  3. 然后查看它们是否被命名为“*ar”(这部分现在不起作用)。

您可能想要做的是:

find -name '*ar' -delete

这将为每个文件查看是否匹配'*ar',只有满足条件才会删除该文件。

抱歉,如果您发现得太晚了。

相关内容