Portanto, o seguinte comportamento do unix find me custou muito:
> touch foo
> touch bar
> ls
bar foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?
Como isso faz sentido?
Portanto, o seguinte comportamento do unix find me custou muito:
> touch foo
> touch bar
> ls
bar foo
> find . -name '*oo' -delete
> ls
bar
> touch baz
> ls
bar baz
> find . -delete -name '*ar'
> ls
> #WHAAAT?
Como isso faz sentido?
Respostas:
A linha de comando de localização é feita a partir de diferentes tipos de opções, combinadas para formar expressões.
A find
opção -delete
é uma ação.
Isso significa que é executado para cada arquivo correspondido até o momento.
Como primeira opção após os caminhos, todos os arquivos são correspondidos ... oops!
É perigoso - mas a página de manual tem pelo menos um grande aviso :
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.
Mais adiante em 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.
Ao experimentar o que um find
comando fará:
Para ver como é um comando
find . -name '*ar' -delete
excluir, você pode substituir a ação -delete
por uma ação mais inofensiva - como -fls
ou -print
:
find . -name '*ar' -print
Isso imprimirá quais arquivos são afetados pela ação.
Neste exemplo, a -print pode ser deixada de fora. Neste caso, não há ação em tudo, então o mais óbvio é adicionado implicitamente: -print
. (Veja o segundo parágrafo da seção "EXPRESSÕES" citadas acima)
-delete
flag :-) Mas há alguma razão que ninguém jamais iria fazer find . -delete
, em vez de rm -rf .
? Ou será que é assim que find
analisa e processa seus argumentos?
warning: use -depth when testing stuff you later want to -delete
que você não fez no seu exemplo prático?
-n
opção; O primeiro comando não deve ter nenhum uso prático, é claro; Eu vou mudar isso.
Na find
ordem dos argumentos importa muito.
Os argumentos podem ser opções, testes e ações. Você normalmente deve usar as opções primeiro, depois os testes e as ações.
Às vezes find
até avisa sobre uma possível má ordem (por exemplo, quando você usa -maxdepth
depois de outros argumentos), mas outras parece que não.
O que find . -delete -name '*ar'
faz é:
O que você provavelmente quer fazer é:
find -name '*ar' -delete
Para cada arquivo, isso verificará se ele corresponde '*ar'
e, somente se satisfizer a condição, o arquivo será excluído.
Desculpe se você descobriu tarde demais.