Como rm -r remove recursivamente? Em que ordem?

Como rm -r remove recursivamente? Em que ordem?

Existe alguma ordem de operações para rm? Executei rmem um diretório grande e estou curioso para saber onde devo procurar para ver o que pode ter sido excluído. Funciona rmprimeiro 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 timecomando 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 lson Dest/ mostrou que havia arquivos e diretórios nas duas extremidades do alfabeto (por exemplo, AFile.txt.... .... Zoo.txt).

Tive sorte e cancelei rmantes de causar estragos no meu diretório Dest/? É rmrealmente tão lento (felizmente!)?

Caso contrário, como rmremover 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 -rtrabalha em cada um de seus argumentos por vez. Se um argumento for um diretório, ele lista o diretório (com oopendirereaddirfunçõ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 lsou echo *classifique os arquivos em ordem lexicográfica de seus nomes. finde ls -fnã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 rmpassou foi um diretório ou não.

A velocidade rmdepende 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.

informação relacionada