Existe alguma ordem de operações para rm
? Executei rm
em um diretório grande e estou curioso para saber onde devo procurar para ver o que pode ter sido excluído. Funciona rm
primeiro nos arquivos e depois nos diretórios? Ou é baseado em alguma informação da tabela de inodes?
Especificações: rm do sistema GNU coreutils 8.22: Arch Linux rodando em um sistema de arquivos beagleboneblack operando em um Seagate HDD externo (ext4) usando USB 2.0.
História de fundo:
Eu estava realizando uma limpeza de diretório e executei
cp -r A/ B/ C/ Dest/
Involuntariamente, eu segui isso com
rm -r A/ B/ C/ Dest/
quando eu pretendia simplesmente atuar
rm -r A/ B/ C/
Eu peguei isso e apertei Ctrl+ Cantes que muito tempo passasse. Especificamente, foram <3 segundos porque eu estava usando o time
comando em conjunto com rm
& cp
. Entrei e examinei Dest/
esperando que fosse inexistente, mas eis que estava inteiro eapareceupara não ser afetado. Isto é um pouco surpreendente, pois A/
B/
C/
eram muito pequenos. Talvez 100–200 MB no total. Dest/
no entanto, tem apenas 1 TB. A execução de um ls
on Dest/ mostrou que havia arquivos e diretórios nas duas extremidades do alfabeto (por exemplo, AFile.txt
.... .... Zoo.txt
).
Tive sorte e cancelei rm
antes de causar estragos no meu diretório Dest/? É rm
realmente tão lento (felizmente!)?
Caso contrário, como rm
remover recursivamente coisas de modo que eu possa adivinhar o que pode ter sido perdido?
Não estou realmente esperando recuperar o que posso ter perdido, apenas curioso para saber o que potencialmente foi destruído.
Responder1
rm -r
trabalha em cada um de seus argumentos por vez. Se um argumento for um diretório, ele lista o diretório (com oopendir
ereaddir
funções ou algum método equivalente) e opera em cada entrada por vez. Se uma entrada for um diretório, ele explora essa entrada recursivamente.
Este é exatamente o mesmo método que outros aplicativos usam para percorrer diretórios recursivamente — find
, ls -Rf
, etc.
A ordem de travessia é imprevisível. Na maioria dos sistemas de arquivos, a ordem é reproduzível desde que nenhum arquivo seja adicionado, removido ou renomeado no diretório (a ordem poderia, em teoria, ser completamente aleatória e mudar sempre, mas não consigo pensar em um sistema de arquivos onde isso aconteça). Em alguns sistemas de arquivos, a ordem pode geralmente ser deduzida dos nomes dos arquivos ou da ordem em que os arquivos foram criados ou de uma combinação de ambos, mas você precisa conhecer os detalhes do sistema de arquivos, e isso pode variar dependendo a versão do driver. A ordem de travessia não é algo em que você possa confiar.
Observe que ls
ou echo *
classifique os arquivos em ordem lexicográfica de seus nomes. find
e ls -f
não classifique.
A única coisa em que você pode confiar é que os argumentos são tratados em ordem. Então, se C/
ainda estivesse parcialmente lá, isso significaria que Dest/
estava intocado. Se C/
tiver desaparecido, você pode ter uma ideia de onde os arquivos foram removidos Dest/
verificando os horários de modificação do diretório e comparando-os com o horário C/
em que foram excluídos ou o horário em que a cópia terminou. O primeiro arquivo a ser excluído pode ser um arquivo diretamente Dest/
ou em algum lugar profundo na hierarquia, dependendo se a primeira entrada Dest/
que rm
passou foi um diretório ou não.
A velocidade rm
depende principalmente de quantos arquivos existem para excluir. É necessário um arquivo muito grande para ter um impacto perceptível no tempo de exclusão. A maior parte do trabalho é excluir cada entrada do diretório por vez. Os dados do arquivo não são apagados, para apagar o conteúdo de um arquivo é necessário apenas marcar os blocos que ele estava usando como livres, o que é relativamente rápido.
Responder2
Como diz Gilles, geralmente não é possível prever a ordem das exclusões dentro de um diretório, apenas que os diretórios de nível superior serão processados na ordem na linha de comando.
No entanto, você também tem a garantia de que as hierarquias de diretórios serão excluídas de baixo para cima, porque o Unix só permite que os diretórios sejam excluídos se estiverem vazios. Portanto, para excluir um diretório, primeiro é necessário remover tudo que está nele. Se contiver subdiretórios, primeiro será necessário remover seu conteúdo e assim por diante.