Um problema com rm -rf *
, ou seu equivalente mais correto rm -rf -- *
é que o shell tem que listar todos os arquivos (não ocultos) no diretório atual, classificá-los e passá-los para rm
, que se a lista de arquivos no diretório atual for grande, isso adicionará alguma sobrecarga extra desnecessária e poderá até falhar se a lista de arquivos for muito grande.
Normalmente, você faria rm -rf .
(o que também teria o benefício de excluir arquivos ocultos também). Mas a maioria das implementações rm
, incluindo todas as em conformidade com POSIX, recusarão fazê-lo. A razão é que alguns shells (incluindo todos os POSIXs) têm um erro na especificação de que a expansão de .*
glob incluiria .
e ..
. O que significaria que rm -rf .*
excluiria o diretório atual e o diretório pai, portanto, rm
foi modificado para contornar essa má especificação desses shells.
Alguns shells como pdksh
(e outros derivados shell de Forsyth), zsh
ou fish
não têm esse tipo de falha. zsh
tem rm
embutido que você pode ativar com autoload zsh/files
, pois zsh
.*
não inclui .
nem ..
funciona OK com rm -rf .
. Então, em zsh
, você pode fazer:
autoload zsh/files
rm -rf .
No Linux, você pode fazer:
rm -rf /proc/self/cwd/
para esvaziar o diretório atual ou:
rm -rf /dev/fd/3/ 3< some/dir
para esvaziar um diretório arbitrário.
(observe o trailing /
)
Nos sistemas GNU, você pode fazer:
find . -delete
Agora, se o diretório atual tiver apenas algumas entradas e a maior parte dos arquivos estiverem em subdiretórios, isso não fará uma diferença significativa e rm -rf -- *
provavelmente será o mais rápido possível. É esperado que rm -rf
(ou qualquer coisa que remova todos os arquivos) seja caro, pois significa ler o conteúdo de todos os diretórios e chamar unlink()
em cada entrada. unlink()
em si pode ser muito caro, pois envolve a modificação do inode do arquivo excluído, o diretório que contém o arquivo e algum mapa do sistema de arquivos ou outras áreas que são gratuitas.
rm
e find
(pelo menos as implementações GNU) já classificam a lista de arquivos pelo número de inode em cada diretório, o que pode fazer uma grande diferença em termos de desempenho em sistemas de arquivos ext4, pois reduz o número de mudanças aos dispositivos de bloco subjacentes quando inodes consecutivos (ou próximos uns dos outros) são modificados em sequência.
rsync
ordena os arquivos pelo nome, o que poderia reduzir drasticamente o desempenho, a menos que a ordem por nome coincidisse com a ordem secundária (como quando os arquivos foram criados a partir de uma lista classificada de nomes de arquivos).
Um motivo pelo qual rsync
pode ser mais rápido em alguns casos é que ele não parece tomar precauções de segurança para evitar condições de corrida que poderiam fazer com que ele caísse no diretório errado se um diretório fosse substituído por um symlink trabalhando como rm
ou find
do.
Para otimizar um pouco mais:
Se você souber a profundidade máxima da sua árvore de diretórios, poderá passá-la para find
:
find . -maxdepth 3 -delete
Isso economiza find
tendo que tentar ler o conteúdo dos diretórios na profundidade 3.