Temos um problema com uma pasta que se torna pesada com centenas de milhares de arquivos minúsculos.
Existem tantos arquivos que executar rm -rf
retornam um erro e, em vez disso, o que precisamos fazer é algo como:
find /path/to/folder -name "filenamestart*" -type f -exec rm -f {} \;
Isso funciona, mas é muito lento e constantemente falha ao ficar sem memória.
Existe uma maneira melhor de fazer isso? Idealmente, eu gostaria de remover o diretório inteiro sem me preocupar com o conteúdo dele.
linux
command-line
files
rm
Toby
fonte
fonte
rm -rf *
na pasta provavelmente falha por causa de muitos argumentos; mas erm -rf folder/
se você quiser remover todo o diretório?rm -rf
?fsck
-lo para recuperar os blocos de disco não utilizados, mas essa abordagem parece arriscada e pode não ser mais rápida. Além disso, a verificação do sistema de arquivos pode envolver percorrer recursivamente a árvore do sistema de arquivos.ccache
árvore de arquivos tão grande erm
demorava tanto (e tornando o sistema lento), era consideravelmente mais rápido copiar todos os outros arquivos do sistema, formatar e copiá-los novamente. Desde então, eu dou a essas árvores de arquivos pequenos e enormes o seu próprio sistema de arquivos dedicado, para que você possamkfs
diretamente em vez derm
.Respostas:
Usar o rsync é surpreendente, rápido e simples.
A resposta do @ sarath mencionou outra opção rápida: Perl! Seus benchmarks são mais rápidos que
rsync -a --delete
.Fontes:
fonte
rsync
pode ser mais rápido que o normalrm
, porque garante as exclusões na ordem correta, portanto, é necessária menos recomputação de btress. Veja esta resposta serverfault.com/a/328305/105902-P
opção ao rsync para mais exibição, tenha cuidado com a sintaxe, as barras finais são obrigatórias. Finalmente, você pode iniciar o comando rsync pela primeira vez com a-n
opção primeiro de iniciar uma execução a seco .-a
iguais-rlptgoD
, mas somente para exclusão-rd
é necessárioAlguém no Twitter sugeriu usar em
-delete
vez de-exec rm -f{} \;
Isso melhorou a eficiência do comando, mas ainda usa recursão para passar por tudo.
fonte
find
tem-delete
, e outrosfind
talvez.-delete
sempre deve ser preferido-exec rm
quando disponível, por razões de segurança e eficiência.Que tal algo como:
find /path/to/folder -name "filenamestart*" -type f -print0 | xargs -0rn 20 rm -f
Você pode limitar o número de arquivos a serem excluídos de uma só vez, alterando o argumento para o parâmetro
-n
. Os nomes dos arquivos com espaços em branco também estão incluídos.fonte
-n 20
bit, pois o xargs deve se limitar a tamanhos aceitáveis de lista de argumentos.man xargs
:(...) max-chars characters per command line (...). The largest allowed value is system-dependent, and is calculated as the argument length limit for exec
. Portanto, a-n
opção é para os casos em que o xargs não pode determinar o tamanho do buffer da CLI ou se o comando executado possui alguns limites.Um truque inteligente:
É super intensivo em CPU, mas realmente muito rápido. Consulte https://web.archive.org/web/20130929001850/http://linuxnote.net/jianingy/en/linux/a-fast-way-to-remove-huge-number-of-files.html
fonte
rsync -a --delete
vs 43 paralsdent
. A razão 10x foi paratime ls -1 | wc -l
vstime ./dentls bigfolder >out.txt
(que é uma comparação parcialmente justa por causa de> file
vswc -l
).Expandindo um dos comentários, não acho que você esteja fazendo o que pensa que está fazendo.
Primeiro, criei uma enorme quantidade de arquivos para simular sua situação:
Depois, tentei o que esperava falhar e o que parece que você está fazendo na pergunta:
Mas isso faz o trabalho:
fonte
rm -Rf bigdirectory
várias vezes. Eu tinha um diretório com milhares de milhões de subdiretórios e arquivos. Eu não poderia mesmo funcionarls
oufind
oursync
nesse diretório, porque ele ficou sem memória. O comando érm -Rf
fechado várias vezes (sem memória), excluindo apenas parte dos bilhões de arquivos. Mas depois de muitas tentativas, ele finalmente fez o trabalho. Parece ser a única solução se ficar sem memória o problema.Tive a oportunidade de testar
-delete
em comparação com-exec rm \{\} \;
e para mim-delete
foi a resposta para esse problema.O uso de
-delete
arquivos excluídos em uma pasta de 400.000 arquivos pelo menos 1.000 vezes mais rápido querm
.O artigo 'Como excluir grande número de arquivos no Linux' sugere que é cerca de três vezes mais rápido, mas no meu teste a diferença foi muito mais dramática.
fonte
find -exec
executa orm
comando para cada arquivo separadamente, é por isso que é tão lento.Sobre a
-delete
opção acima: Estou usando-o para remover um grande número de arquivos (1M + est) em uma pasta temporária que eu criei e esqueci inadvertidamente a limpeza noturna. Enchi meu disco / partição acidentalmente e nada mais poderia removê-los, a não ser ofind .
comando. Está lento, no começo eu estava usando:Mas isso levou um tempo EXTREMO. Ele foi iniciado após cerca de 15 minutos para remover alguns arquivos, mas meu palpite é que ele estava removendo menos de 10 ou mais por segundo depois que finalmente foi iniciado. Então, eu tentei o:
em vez disso, e estou deixando isso funcionar agora. Parece estar rodando mais rápido, apesar de estar EXTREMAMENTE sobrecarregando a CPU, o que o outro comando não estava. Está em execução há mais de uma hora e acho que estou recuperando espaço na minha unidade e a partição gradualmente "diminuindo", mas ainda está demorando muito tempo. Eu duvido seriamente que esteja rodando 1.000 vezes mais rápido que o outro. Como em todas as coisas, eu só queria apontar a troca no espaço versus tempo. Se você tiver a largura de banda da CPU de sobra (temos), execute a última. A minha CPU está funcionando (
uptime
relatórios):E já vi a média de carga ultrapassar as 30,00, o que não é bom para um sistema ocupado, mas para o nosso, que normalmente é carregado com pouca carga, fica bom por algumas horas. Eu verifiquei a maioria das outras coisas no sistema e elas ainda respondem, por isso estamos bem por enquanto.
fonte
exec
certamente não quer usar-ls
e ofind . -type f -exec rm '{}' +
+ é mais rápido, pois dará tantos argumentos para a rm quanto ele pode lidar de uma só vez.find … -delete
meionice
ouionice
, que podem ajudar. Portanto, pode alterar algumas opções de montagem para configurações menos seguras contra falhas. (E, claro, dependendo do que o resto é no sistema de arquivos, a maneira mais rápida de eliminar tudo é muitas vezesmkfs
.)1
para máquina de núcleo único é o mesmo que loadavg64
no sistema de 64 núcleos - o que significa que cada CPU está ocupada 100% do tempo.Existem alguns métodos que podem ser usados para excluir um grande número de arquivos no linux. Você pode usar a opção find with delete, que é mais rápida que a opção exec. Então você pode usar o perl unlink e até o rsync. Como excluir um grande número de arquivos no linux
fonte
Considere usar o volume Btrfs e simplesmente exclua o volume inteiro desse diretório com grande número de arquivos.
Como alternativa, você pode criar um arquivo de imagem FS, desmontar e excluir o arquivo para remover tudo de uma só vez muito rápido.
fonte
Supondo que o GNU esteja
parallel
instalado, eu usei isso:parallel rm -rf dir/{} ::: `ls -f dir/`
e foi rápido o suficiente.
fonte
A exclusão de diretórios REALMENTE GRANDES precisa de uma abordagem diferente, como aprendi neste site - você precisará utilizar o ionice. Ele garante (com -c3) que exclusões somente serão executadas quando o sistema tiver tempo de IO para isso. A carga de seus sistemas não aumentará muito e tudo permanecerá responsivo (embora o tempo de busca da CPU tenha sido bastante alto em cerca de 50%).
fonte
+
, em vez de\;
se fazer isso mais rápido que passa mais argumentos para rm ao mesmo tempo, menos bifurcaçãoionice -c3 find <dir> -type f -delete
deve funcionar dentro da pasta principal
fonte
ls
não funcionará devido à quantidade de arquivos na pasta. É por isso que eu tive que usarfind
, obrigado.ls -f
, o que desativa a classificação. A classificação requer que todo o diretório seja carregado na memória para ser classificado. Um não classificadols
deve ser capaz de transmitir sua saída.find . -print0 | xargs -0 rm
, que usará o caractere NULL como separador de nome de arquivo.Para a dica de Izkata acima:
Isso quase funcionou - ou teria funcionado - mas eu tive alguns problemas de permissão; os arquivos estavam em um servidor, mas ainda não entendo de onde veio esse problema de permissão. De qualquer forma, o Terminal pediu confirmação em todos os arquivos. A quantidade de arquivos era de cerca de 20.000, portanto não era uma opção. Depois de "-r", adicionei a opção "-f", então todo o comando foi " rm -r -f foldername / ". Então pareceu funcionar bem. Sou iniciante no Terminal, mas acho que tudo bem, certo? Obrigado!
fonte
Dependendo de quão bem você precise se livrar desses arquivos, sugiro usá-lo
shred
.se você deseja limpar o diretório, mas não pode removê-lo e recriá-lo, sugiro movê-lo e recriá-lo instantaneamente.
isso é mais rápido, acredite ou não, pois apenas um inode deve ser alterado. Lembre-se: você não pode realmente paralelizar essa prova em um computador com vários núcleos. Tudo se resume ao acesso ao disco, limitado pelo RAID ou pelo que você possui.
fonte
shred
não funcionará com muitos sistemas de arquivos modernos.Se você possui milhões de arquivos e todas as soluções acima colocam seu sistema em estresse, tente esta inspiração:
Arquivo
nice_delete
:E agora exclua os arquivos:
O Find criará lotes (consulte
getconf ARG_MAX
) de algumas dezenas de milhares de arquivos e os passará paranice_delete
. Isso criará lotes ainda menores para permitir suspensão quando a sobrecarga for detectada.fonte
Se você quiser se livrar de muitos arquivos o mais rápido possível,
ls -f1 /path/to/folder/with/many/files/ | xargs rm
pode funcionar bem, mas é melhor não executá-lo nos sistemas de produção, pois seu sistema pode se tornar um problema de E / S e os aplicativos podem ficar presos durante a operação de exclusão.Esse script funciona bem para muitos arquivos e não deve afetar o ioload do sistema.
fonte