find - exec rm vs -delete

260

Estou tentando entender a diferença entre esses dois comandos:

sudo find / -name .DS_Store -delete

e

sudo find / -name ".DS_Store"  -exec rm {} \;

Percebi que o execmétodo é o preferido. Por quê? Qual é o mais seguro / mais rápido / melhor? Eu usei tanto no meu Macbook e tudo parece funcionar bem.

Cebola
fonte

Respostas:

245

-delete terá melhor desempenho porque não precisa gerar um processo externo para cada arquivo correspondente.

É possível que você veja com -exec rm {} \;frequência recomendado, porque -deletenão existe em todas as versões do find. Não posso verificar agora, mas tenho certeza de que usei um findsem ele.

Ambos os métodos devem ser "seguros".

EDIT por comentário de @doitmyway: certifique-se de coincidir com o nome e , em seguida, apagar, não o contrário (apagar, em seguida, combinar). Caso contrário, todos os arquivos serão excluídos, correspondendo ou não . Ou seja, NÃO fazer isso: find / -delete -name .DS_Store.

Um método comum para evitar a sobrecarga de gerar um processo externo para cada arquivo correspondido é:

find / -name .DS_Store -print0 | xargs -0 rm

(mas observe que também há um problema de portabilidade aqui: nem todas as versões do find possuem -print0!)

Celada
fonte
2
Eu vejo. Também li que o uso do -deletecomutador antes -nameexclui a árvore de arquivos especificada, então acho que tenho que ter cuidado.
Cebola
8
Em recente, findvocê pode usar -exec rm {} +para remover todos os arquivos correspondentes com um único rmcomando.
jimmij
3
.DS_Storenão contém caracteres especiais, portanto, as aspas são desnecessárias e não mudam nada nesse caso.
Celada
1
Basicamente, apenas espaço em branco (espaços, tabulações, talvez outros) é a única coisa que faz com que uma sequência não citada seja interpretada como dois argumentos separados da linha de comando, mas não é só isso que você precisa se desculpar ao decidir entre citar ou não. Você precisa se preocupar com todos os metacaracteres do shell, como ;or |ou >or <e `` e muitos outros que têm um significado especial para o shell, a menos que citado.
Celada
1
O @MarcoMarsala xargscuida do problema da lista de argumentos de tamanho limitado de forma transparente, dividindo-o em várias invocações do comando.
Celada
27

Supondo que .DS_Storerepresentam arquivos e não diretórios, a maneira mais portátil e rápida de fazer isso seria:

sudo find / -name .DS_Store -exec rm {} +

O único risco é sudonão estar disponível, mas atualmente é bastante baixo.

A -deleteopção usada para exigir a localização do GNU e ainda não é padrão em muitas outras findimplementações, portanto nem sempre está disponível.

A finalização do comando, em +vez de \;otimizar a execcláusula, não executa o rmcomando para todos os .DS_Storepresentes no sistema de arquivos.

jlliagre
fonte
16

Para uma máquina como o seu macbook, você não encontrará muita diferença no desempenho entre os dois comandos. No entanto, se você olhar para a versão -exec, poderá ver uma diferença sutil:

sudo find / -iname ".file-to-delete"  -exec rm {} \;

Isso significa que você encontrará todos esses arquivos com o nome ".arquivo para excluir". No entanto, essa pesquisa pode retornar alguns falsos positivos indesejados. Ao fazer algo com o sudo, você deve ter um pouco mais de cuidado. A vantagem de usar -exec rm {} é que você pode passar argumentos para rm assim:

sudo find / -iname "*~"  -exec rm -i {} \;

Neste exemplo, quero remover os arquivos de backup que o emacs cria. No entanto, esse til pode estar em algum arquivo obscuro que eu não conheço e pode ser importante. Além disso, quero confirmar a exclusão. Então, eu coloquei a opção '-i' no comando rm. Isso me dará uma exclusão interativa.

Também é possível refinar o uso do rm para excluir diretórios e arquivos:

find /usr/local/share/ -iname "useless" -exec rm -r {} \;

Em resumo, o -exec oferece um pouco mais de controle sobre o comando real que remove o item encontrado. A vantagem é que você usa uma ferramenta para encontrar os arquivos, outra ferramenta para removê-los. Além disso, nem todas as versões do utilitário find têm a opção -delete. Então é melhor usar cada ferramenta para o seu trabalho adequado. Essa é a filosofia do unix - uma ferramenta, um trabalho, use-as juntas para fazer o que você precisa fazer.

Pe. John Jenkins
fonte
3
Consulte também -ok rm {} \;no lugar de -exec rm {} \;para confirmação interativa.
Kusalananda