Existe alguma maneira mais rápida de remover um diretório que "rm -rf"?

32

Eu tenho uma pasta que possui muitos arquivos e "rm -rf" leva muito tempo para ser concluído. Existe alguma maneira mais rápida de remover um diretório e seu conteúdo (subdiretórios, etc)?

Mohammad Moghimi
fonte
Para qualquer um ver interessados: slashroot.in/comment/1286#comment-1286 encontrar trunfos perl trunfos rsync
Rinzwind

Respostas:

33

Você pode tentar desvincular o inode do diretório, mas isso deixaria uma carga completa de arquivos órfãos que fsck serão revertidos.

rm é tão bom quanto ele ganha.


Algumas pessoas estão mencionando casos extremos onde algumas coisas são mais rápidas que outras. Mas vamos ter certeza de que estamos comparando as melhores versões das mesmas coisas.

Se você deseja excluir um diretório e tudo o mais, sugiro:

rm -rf path/to/directory

rmlistará internamente os arquivos e diretórios que serão excluídos. E isso é tudo em C compilado . São essas duas razões pelas quais é mais rápido.

Isso não é exatamente o mesmo rm -rf path/to/directory/*que irá expandir no nível do shell e passar uma carga de argumentos para rm. Então rmtem que analisar aqueles e recursar de cada um. Isso é muito mais lento.

Assim como uma "referência" que compara find path/to/directory -exec {} \;é um absurdo. Isso é executado rmuma vez por arquivo encontrado. Tão lento. O Find pode criar argumentos de comandos no estilo xargs, -exec rm {} +mas isso é tão lento quanto a expansão. Você pode chamar -deleteque usa uma unlinkchamada interna para o kernel (como rmfaz), mas isso só funcionará para arquivos no início.

Então, repetir, a menos que você jogue o disco no magma líquido quente, rmé o rei .


Em uma nota relacionada, diferentes sistemas de arquivos excluem as coisas em taxas diferentes devido à forma como elas são estruturadas. Se você estiver fazendo isso regularmente, convém armazenar esses arquivos em uma partição formatada no XFS, que tende a lidar com exclusões muito rapidamente.

Ou use um disco mais rápido. Se você tem toneladas de RAM, usar /dev/shm(um disco RAM) pode ser uma ideia.

Oli
fonte
Você não pode realmente usar a unlinkchamada do sistema nos diretórios (você receberá um EISDIRerro), portanto a primeira opção não é possível.
James Henstridge 22/03
O mv para / tmp seria mais rápido? Parece que mv também leva muito tempo.
Mohammad Moghimi 22/03
@MohammadMoghimi: mventre diferentes sistemas de arquivos / partições significa a cpseguido de a rm.
enzotib 22/03/12
3
@enzotib No entanto, se /tmpestiver no mesmo sistema de arquivos, gostaria de saber se a mvreinicialização seria mais rápida? Não tenho certeza se /tmpé limpo usando de rmqualquer maneira.
Sparhawk #
11
rsyncneste caso de referência é mais rápido que rm -rf: web.archive.org/web/20130929001850/http://linuxnote.net/…
schmijos
11

Às vezes, find $DIR_TO_DELETE -type f -deleteé mais rápido que rm -rf.

Você também pode querer experimentar mkdir /tmp/empty && rsync -r --delete /tmp/empty/ $DIR_TO_DELETE.

Finalmente, se você precisar excluir o conteúdo de uma partição inteira, o mais rápido será, provavelmente umount, mkfse re mount.

mivk
fonte
11
não é type -fdenotar um arquivo e não um diretório? Além disso, adicionar -printmostra os arquivos à medida que eles estão sendo excluídos.
leetbacoon 25/03
8

Se você não precisar do espaço livre, a maneira mais rápida é atrasar a exclusão e fazer isso em segundo plano:

  • mkdir .delete_me
  • mv big-directory-that-i-want-gone .delete_me

Em seguida, tenha um crontab que faça isso em segundo plano, em um momento silencioso, com uma baixa prioridade de E / S:

3 3 * * * root ionice -c 3 nice find /path/to/.delete_me -maxdepth 1 ! -name \. -exec echo rm -rf "{}" +

Notas:

  • verifique sua saída antes de remover o eco no crontab!
  • o diretório .delete_me deve estar no mesmo sistema de arquivos - caso isso não seja óbvio para todos.

Atualização: Encontrei um truque interessante para executar várias rm em paralelo - isso ajudará se você tiver uma grande matriz de discos:

ionice -c 3 nice find target_directory -depth -maxdepth 3 | xargs -d \n -P 5 -n 5 rm -rf
  • -thpth para fazer uma travessia em profundidade.

  • -maxdepth para limitar a profundidade da passagem do diretório, para que não acabemos ouvindo arquivos individuais.

  • -d \ n para manipular espaços nos nomes de arquivos.

  • -P e -n lida com o grau de paralelismo (verifique a página de manual).

ref: http://blog.liw.fi/posts/rm-is-too-slow/#comment-3e028c69183a348ee748d904a7474019

Atualização 2 (2018): Com o ZFS enviado com o Ubuntu 18.04, eu o uso para tudo e vou criar um novo conjunto de dados para qualquer grande projeto. Se você planeja com antecedência e faz isso de antemão, pode simplesmente "zfs destruir" um sistema de arquivos quando terminar. ;-)

Usei as instruções do wiki zfsonlinux para instalar o Ubuntu no ZFS nativamente: https://github.com/zfsonlinux/zfs/wiki/Ubuntu-18.04-Root-on-ZFS

Lester Cheung
fonte
2
Em vez do último comando, use find target_dir -maxdepth 3 -depth -type d -print0 | xargs -0 -P 5 rm -rf. A -depthopção diz findpara listar os filhos primeiro.
muru 9/03/16
2

Penso que a questão é que não existe uma maneira perfeita de remover um diretório muito grande e todo o seu conjunto de conteúdos sem um verdadeiro sistema de arquivamento indexado que entenda a desvinculação e não significa que ele acha que faltam arquivos no FSCK. Tem que haver uma confiança.

Por exemplo, tenho zoneminder correndo para um campo de golfe. Eu construí um ataque linux de 1,5 TB para lidar com a imensa quantidade de dados que ela captura por dia (12 feeds de câmera), como ela rodava em uma unidade de 120 GB está além de mim. Para encurtar a história, a pasta de todos os dados capturados representa cerca de 1,4 TB de seu armazenamento. Muito a limpar

Ter que reinstalar o ZM e limpar a biblioteca antiga de 1,4 TB não é divertido, pois pode levar de 1 a 2 dias para excluir as imagens antigas.

Um verdadeiro FS indexado permite a queda do diretório e sabe que os dados dele estão mortos e zerar os dados é um desperdício de nosso tempo e recursos do PC. Deve ser uma opção para zerar os dados excluídos. A RM leva muito tempo no mundo real no ext4.

Resposta: Desvincular todos os arquivos recursivamente seria mais rápido marginalmente, mas você ainda precisaria reservar um tempo para executar o FSCK.

Crie um script executando um comando "FOR" recursivo que possa "desvincular" todos os arquivos em suas pastas e, em seguida, apenas rm ou rmdir todas as pastas para limpá-lo. Execute manualmente o FSCK para zerar o restante dos dados quando for conveniente. Kinda preguiçoso não escrevê-lo desculpe :).

Adam Lazo
fonte
0

Embora não seja útil se você deseja limpar um diretório existente, mencionarei que uma estratégia possível, se você souber que terá um diretório com vários arquivos dos quais precisará limpar regularmente, é colocar o diretório em seu próprio sistema de arquivos ( por exemplo , partição). Então, quando precisar limpá-lo, desmonte-o, execute mkfsae remonte-o. Por exemplo, o OpenBSD recomenda fazer isso para/usr/obj , onde muitos arquivos são criados durante uma compilação do sistema e devem ser excluídos antes da próxima compilação.

Fkraiem
fonte