Usando 'find' para excluir

7

Então, dadas três opções ...

  1. find .... -delete
  2. find .... | xargs rm ...
  3. find .... -exec rm ...;

.. ou suas variações, qual opção é preferível?
Eu estou supondo que não há resposta dura e rápida, e uma situação específica ditará a melhor opção (por favor nomeie-os!)

Felicidades.

    
por Ben Davies 28.07.2010 / 15:27

3 respostas

15

A opção 1 evitará a geração de processos externos, o que é útil sob condições de estresse.

A Opção 2 gerará um único processo xargs , que gerará apenas quantos rm processar conforme necessário. Essa opção é normalmente usada com -print0 e -0 para manipular nomes de arquivos com espaços e / ou novas linhas.

A opção 3 gerará um processo rm para cada arquivo.

O GNU find (ou qualquer versão do find compatível com POSIX) permite uma quarta opção, find .... -exec rm -r {} + , que executará rm com tantos nomes de arquivos quanto possível para gerar apenas um número limitado deles.

    
por 28.07.2010 / 15:32
5

Eu prefiro usar find ... > file.txt para revisar o arquivo extensivamente, então use find ... -delete , então eu sei exatamente se os mesmos resultados serão deletados (passar argumentos é quase sempre à prova de balas, principalmente).

    
por 28.07.2010 / 15:32
2

O tópico da exclusão de arquivos é abordado na seção "Limpeza" na documentação do GNU findutils. Você pode ler isso em seu sistema usando "info find" ou dentro do Emacs. Você também pode visualizá-lo on-line no link .

find .... -delete

Esta é a opção mais segura (contra corridas de links simbólicos) e de alto desempenho (já que não há necessidade de executar nada ou executar uma alternância de contexto quando o buffer de canal está cheio). Mas tenha em mente que -delete implica -depth.

find .... | xargs rm ...

Isso é perigoso em situações em que outros têm acesso de gravação à árvore na qual você está fazendo a limpeza. Por exemplo, supondo que o comando find tenha decidido que /var/tmp/scratch/me/.ssh/config corresponde aos seus requisitos e, portanto, imprime esses nomes para stdout. O comando xargs lerá isso e o adicionará a uma estrutura de dados. Pouco tempo depois (quando xargs leu o número de bytes indicado pelo valor padrão da opção -s) os xargs irão bifurcar e executar rm para deletá-lo. No entanto, é possível que, no meio tempo, outra pessoa tenha feito isso:

$ cd /var/tmp/scratch
$ mv me me.old
$ ln -s /root me

Então, quando o rm apagar o /var/tmp/scratch/me/.ssh/config, ele emitirá a chamada do sistema unlink ("/ var / tmp / scratch / me / .ssh / config"). Como o kernel resolverá o link simbólico para você, isso é equivalente a ele chamar unlink ("/ root / .ssh / config"). Se o processo xargs estava rodando como root, então /root/.ssh/config será deletado, apesar do fato de que você não especificou -L na linha de comando. Por esse motivo, se a segurança for importante, use -delete. Você pode ler mais sobre esta área na seção "Considerações sobre Segurança" do manual de busca GNU.

find .... -exec rm ...;

Como isso também envolve fork / exec, ele tem os mesmos problemas de segurança que mencionei acima.

Em suma, a única razão para não usar -delete é a compatibilidade com sistemas que não têm suporte para -delete.

    
por 12.02.2012 / 16:44

Tags