A sugestão de ire_and_curses de usar tar c <dir>
tem alguns problemas:
- O tar processa as entradas do diretório na ordem em que são armazenadas no sistema de arquivos e não há como alterar essa ordem. Isso efetivamente pode gerar resultados completamente diferentes se você tiver o diretório "mesmo" em locais diferentes, e não sei como corrigir isso (o tar não pode "classificar" seus arquivos de entrada em uma ordem específica).
- Eu geralmente me importo se os números groupid e ownerid são os mesmos, não necessariamente se a representação em string do grupo / owner é a mesma. Isso está alinhado com o que, por exemplo,
rsync -a --delete
faz: sincroniza praticamente tudo (menos xattrs e acls), mas sincroniza o proprietário e o grupo com base em seu ID, não na representação de cadeias. Portanto, se você sincronizou com um sistema diferente que não necessariamente tem os mesmos usuários / grupos, adicione o --numeric-owner
sinalizador ao tar
- O tar incluirá o nome do arquivo do diretório que você está verificando, apenas algo para estar ciente.
Enquanto não houver solução para o primeiro problema (ou a menos que você tenha certeza de que isso não o afeta), eu não usaria essa abordagem.
As find
soluções baseadas propostas acima também não são boas, pois incluem apenas arquivos, não diretórios, o que se torna um problema se você usar a soma de verificação em diretórios vazios.
Por fim, a maioria das soluções sugeridas não é classificada de maneira consistente, pois o agrupamento pode ser diferente entre os sistemas.
Esta é a solução que eu vim com:
dir=<mydir>; (find "$dir" -type f -exec md5sum {} +; find "$dir" -type d) | LC_ALL=C sort | md5sum
Notas sobre esta solução:
- O
LC_ALL=C
objetivo é garantir uma ordem de classificação confiável entre os sistemas
- Isso não diferencia entre um diretório "nomeado \ nwithanewline" e dois diretórios "nomeado" e "withanewline", mas a chance de isso ocorrer parece muito improvável. Geralmente, isso é corrigido com um
-print0
sinalizador, find
mas, como há outras coisas acontecendo aqui, só consigo ver soluções que tornariam o comando mais complicado do que vale a pena.
PS: um dos meus sistemas usa um busybox limitado find
que não suporta -exec
nem -print0
sinalizadores, e também adiciona '/' para indicar diretórios, enquanto o findutils find não parece, então, para esta máquina, preciso executar:
dir=<mydir>; (find "$dir" -type f | while read f; do md5sum "$f"; done; find "$dir" -type d | sed 's#/$##') | LC_ALL=C sort | md5sum
Felizmente, não tenho arquivos / diretórios com novas linhas em seus nomes, portanto isso não é um problema nesse sistema.