因此,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'
的是:
- 在当前目录上查找文件和目录。
- 发现它们后将其全部删除!
- 然后查看它们是否被命名为“*ar”(这部分现在不起作用)。
您可能想要做的是:
find -name '*ar' -delete
这将为每个文件查看是否匹配'*ar'
,只有满足条件才会删除该文件。
抱歉,如果您发现得太晚了。