Como posso excluir rapidamente uma pasta com muitas subpastas?

15

Eu tenho uma pasta com 266778 subpastas. Como posso excluí-lo?

eu tentei

cd ~/.local/share/Trash/
sudo rm -rf *

mas leva muito tempo. Após 1 minuto e 25 segundos em tempo real e 0,072 segundos em tempo de usuário, ele excluiu apenas 2500 pastas. Dessa forma, levará mais de duas horas para excluir esta pasta.

Existe uma maneira mais rápida de excluir esta pasta? Por que existe uma diferença tão grande entre o tempo do usuário e o tempo real?

real    1m25.474s
user    0m0.072s
sys     0m28.142s

Eu uso o Linux 2.6.32 (Ubuntu 10.04.4 LTS).

Martin Thoma
fonte
Acabei de pesquisar esse problema no Google e parece que algumas pessoas descobriram que o rsync pode ser usado como uma ferramenta de "exclusão de muitos arquivos" com bastante eficiência. Se é realmente mais rápido, depende de você avaliar.
9608 Johan Johan
2
Para o que vale a pena: o desempenho ao excluir muitas pastas / arquivos depende muito do sistema de arquivos. Na minha experiência, a diferença ao excluir milhões de arquivos pequenos no ext3 (lento) vs. XFS (rápido) pode levar horas.
Pdo
Se você costuma ter esse caso e pode planejar com antecedência, usando um sistema de arquivos como btrfs e subvolume, é possível acelerar as coisas rapidamente, basta descarregar esse subvolume.
PlasmaHH 18/04
Aqui é onde você pode encontrar a resposta. O perl é o mais rápido. unix.stackexchange.com/questions/37329/…
SDsolar 17/17

Respostas:

17

Se sua versão de "find" implementa o subcomando -delete, você pode tentar

find directory -delete

Nesse caso:

find ~/.local/share/Trash/ -delete

Alguns comandos, como rm, executam a maior parte de seu trabalho no kernel. Nas rotinas do sistema de arquivos, para ser exato. O tempo gasto na execução de chamadas do sistema é contabilizado dessa maneira, portanto, embora o comando "rm" seja executado por um longo período de tempo, ele não faz muito trabalho na área do usuário - as chamadas do sistema executam a maior parte do trabalho.

Johan
fonte
+1; embora isso também elimina a dir pai e eu suspeito que o OP só queria excluir o conteúdo da pasta de lixo não a própria pasta
don_crissti
1
@don_crissti: boa observação. se o OP quis excluir apenas subdiretórios em ~ / .local / share / Trash (e não arquivos no 1º nível), então: find ~/.local/share/Trash/*/ -delete (é claro, isso também excluirá arquivos (e diretórios) em qualquer um desses Lixeira / * / (subdireta também))
Olivier Dulac
2
+1 para explicar o comportamento estranho detime
Martin Thoma
3
É find directory -deleterealmente mais rápido do que rm -rf directory? Afinal, eles executam o mesmo trabalho e não há duas maneiras de fazê-lo.
Gilles 'SO- stop be evil'
1
@Johan encontrar é muito rápido. Você já teve a chance de descobrir o motivo?
Harshdeep
20

Depende da sua definição de rápido . As respostas já aqui oferecem uma boa solução para remover os diretórios do sistema de arquivos, mas se você realmente precisa liberar o nome do diretório o mais rápido possível, uma renomeação no mesmo sistema de arquivos é instantânea:

{ mv directory directory.gone && rm -rf directory.gone; } &

Tecnicamente, isso é trapaça, pois eu não acelerei a exclusão real, mas praticamente é muito útil: eu uso esse truque o tempo todo para não ter que esperar pelas operações de exclusão lenta.

kojiro
fonte
Ótimo. Qual é o seu caso de uso para fazer isso o tempo todo? Se você fizer muito, não há o risco de acumular backlog, obter vários 'directory.gone's e falhar? Eu presumo que você use um sufixo como '$$' ou '% (data ...)'
SMCI
1
Se eu precisasse, provavelmente poderia usar o mktemp com argumentos que garantem que ele permaneça no mesmo sistema de arquivos. Mas não posso dizer que tenho um exemplo específico agora.
Kojiro # 28/17
kojiro sim graças, mktempé o que eu estava tentando lembrar ...
SMCI
1

rm -rf directoryou rm -rf *, é claro, é o método mais rápido, a menos que sua rmimplementação local esteja quebrada.

O uso findnão oferece vantagens.

Se isso é rápido ou lento, depende principalmente do sistema de arquivos e da implementação do SO. Portanto, a pergunta parece inadequada.

UFS e ZFS no Solaris são conhecidos por ser muito rápido com este tipo de tarefa como ambas as implementações de sistemas de arquivos incluem adiada código de exclusão de fundo que faz com que o unlink()e rmdir()chamadas para retornar rápido mesmo quando o objeto relacionado levará mais tempo no total.

Com a exclusão em segundo plano atrasada no kernel, as atualizações de diretório também podem ser feitas rapidamente e isso ajuda a acelerar toda a operação.

esperto
fonte
Embora alguém possa ser perdoado por pensar isso, na verdade isso não é verdade, como esta resposta descreve.
Hitechcomputergeek
0

Essa é apenas uma resposta parcial, esclarecendo os três valores que o comando retorna; citado na página de time(1)manual :

(i) o tempo real decorrido entre a chamada e a rescisão, (ii) o tempo de CPU do usuário (a soma dos valores tms_utimee tms_cutimeem a, struct tmsconforme retornado portimes(2) ) e (iii) o tempo de CPU do sistema (a soma dos valores tms_stimee tms_cstimeem um struct tmsconforme retornado por times(2)) ".

Schaiba
fonte