Verifique o conteúdo do arquivo procurando corrupção, o tamanho do arquivo indica o tamanho "zero"

3

Eu tenho uma situação muito estranha, onde eu tenho um sistema de arquivos que contém um número de arquivos que são de tamanho variável, mas parece ter sido corrompido e não mostrar nenhum conteúdo ao catar o arquivo.

Eu não tenho ideia de quantos desses arquivos existem e eles se parecem com todos os outros arquivos ao redor deles. Até agora, o melhor método que encontrei para descobri-los é executar find . -type f | xargs wc -l e procurar os arquivos que retornam 0.

No entanto, alguns desses arquivos têm 10s de GB e, mesmo quando estão vazios, demoram mais de um minuto para verificar um arquivo. Eu tenho que checar aproximadamente 50 milhões de arquivos, então isso é praticamente um não-iniciante.

A minha maior pergunta é se existe um modo de baixo nível para verificar o conteúdo desses arquivos que será muito mais rápido do que executar uma simples descoberta.

    
por Kevin L 15.11.2016 / 16:41

3 respostas

4

and show no contents when cat-ing the file.

Nenhuma saída de cat para um arquivo não implica que o arquivo esteja vazio, como mostra a seguinte experiência:

$ truncate -s 1M foo    
$ ll foo
-rw-r----- 1 user users 1048576 Nov 15 19:28 foo
$ file foo
foo: data
$ cat foo
$ 

cat produz 1MiB de caracteres NUL, mas esses caracteres são invisíveis em um terminal.

Sua pergunta sobre arquivos vazios é um tanto ambígua. O foo acima se qualifica? Se "vazio" significa comprimento zero, então find pode ajudar você:

find dir -type f -empty

lista todos os arquivos com comprimento zero em dir . Se o seu find não suportar -empty , você poderá usar -size 0 .

Em scripts de shell, você pode usar a expressão -s file , que é verdadeira se file existir e não estiver vazia. A fim verificar se um arquivo está vazio (dado que existe) use algo como

if [ \! -s file ] ; then ... ; fi

Como alternativa, você pode usar stat(1) . Aqui com a variante GNU:

$ stat --format=%s foo
1048576

que você pode usar mais em comparações.

    
por 15.11.2016 / 19:50
4

De suas pistas:

  • eles são ou não tamanho 0, conforme relatado por ls -l
  • que cat ing parece não mostrar nada
  • wc -l retorna 0.

Podemos dizer:

  • eles não contêm nenhum caractere de nova linha ( wc -l conta os caracteres de nova linha)
  • se eles contiverem qualquer caractere, eles serão invisíveis em um terminal

Embora haja um grande número de caracteres que são invisíveis em um terminal como a maioria dos caracteres de controle, e alguns unicode estendidos, para muitos arquivos diferentes corrompidos para mostrar que o comportamento me faz pensar que é provável seja o caractere NUL.

Um arquivo corrompido pode ser visto como todo-zero se todas as referências a blocos de dados tiverem sido removidas para ele, com o atributo tamanho no inode deixado intacto. São arquivos totalmente esparsos.

A menos que o campo de contagem de blocos no inode também esteja corrompido, você poderá detectar aqueles com (assumindo o GNU find e awk ):

find . -size +0 -printf '%b%p
find . -size +0 -printf '%b%p%pre%' | awk -v RS='%pre%' '
  /^0/{print substr($0, 2)}'
' | awk -v RS='%pre%' ' /^0/{print substr($0, 2)}'

Ou seja, localizar arquivos cujo tamanho seja diferente de zero, mas o uso do disco é nulo.

    
por 15.11.2016 / 20:22
0

My biggest question is if there's a lower level way to check the contents of these files that will be much faster than running a simple find.

Experimente du :

$ truncate -s 4G my4g
$ ls -l my4g
-rw-rw-r-- 1 tange tange 4294967296 Mar  4 15:34 my4g
$ cat my4g
$ du my4g
0       my4g
    
por 04.03.2017 / 15:36

Tags