Entonces, el siguiente comportamiento de unix find me costó caro:
> touch foo
> touch bar
> ls
bar foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?
¿Cómo esto tiene sentido?
Entonces, el siguiente comportamiento de unix find me costó caro:
> touch foo
> touch bar
> ls
bar foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?
¿Cómo esto tiene sentido?
Respuestas:
La línea de comando de find está hecha de diferentes tipos de opciones, que se combinan para formar expresiones.
La find
opción -delete
es una acción.
Eso significa que se ejecuta para cada archivo que coincida hasta ahora.
Como primera opción después de las rutas, todos los archivos coinciden ... ¡Uy!
Es peligroso, pero la página de manual al menos tiene una gran advertencia :
De 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.
De más arriba en 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.
Al probar lo que find
hará un comando:
Para ver cómo es un comando
find . -name '*ar' -delete
eliminará, primero puede reemplazar la acción -delete
por una acción más inofensiva, como -fls
o -print
:
find . -name '*ar' -print
Esto imprimirá qué archivos se ven afectados por la acción.
En este ejemplo, la impresión se puede omitir. En este caso, no es acción en absoluto, por lo que la más obvia se añade de forma implícita: -print
. (Ver el segundo párrafo de la sección "EXPRESIONES" citado anteriormente)
-delete
bandera :-) Pero, ¿hay alguna razón por la que alguien pueda hacerlo en find . -delete
lugar de hacerlo rm -rf .
? ¿O es que esa es la forma en que find
analiza y procesa sus argumentos?
warning: use -depth when testing stuff you later want to -delete
lo que no hizo en su ejemplo práctico?
-n
opción; El primer comando no debería tener ningún uso práctico, por supuesto; Iré a cambiarlo.
En el find
orden el argumento importa, mucho.
Los argumentos pueden ser opciones, pruebas y acciones. Por lo general, debe usar primero las opciones, luego las pruebas y luego las acciones.
A veces, find
incluso le advierte sobre un posible mal orden (por ejemplo, cuando lo usa -maxdepth
después de otros argumentos), pero otros parece que no.
Lo que find . -delete -name '*ar'
hace es:
Lo que probablemente quieras hacer es:
find -name '*ar' -delete
Esto, para cada archivo, verá si coincide '*ar'
, y solo si cumple con la condición eliminará el archivo.
Lo siento si te enteraste demasiado tarde.