Como verificar se um arquivo Unix .tar.gz é um arquivo válido sem descompactá-lo?

Respostas:

122

Que tal apenas obter uma lista do tarball e descartar a saída, em vez de descompactar o arquivo?

tar -tzf my_tar.tar.gz >/dev/null

Editado conforme comentário. Obrigado zrajm!

Edite conforme o comentário. Obrigado Frozen Flame! Este teste não implica de forma alguma integridade dos dados. Por ter sido projetado como um utilitário de arquivamento em fita, a maioria das implementações do tar permite várias cópias do mesmo arquivo!

Rob Wells
fonte
13
Por que usar -vse você está apenas canalizando a saída /dev/null?
zrajm
2
Verdadeiro @zrajm. Acho que é a minha memória muscular entrando em ação! (-:
Rob Wells
5
A -zopção também é desnecessária. Não faz nada no modo de extração ou lista.
asmeurer
1
@asmeurer Re: -zEsse é definitivamente o caso do GNU tar - você sabe se isso é verdade em outro lugar (BSD, etc.)?
belacqua
2
@bobwells Mas a descompactação bem-sucedida ou a listagem de arquivos de conteúdo implica integridade de dados do tar.gz? Alguma informação de suporte?
Frozen Flame de
99

você provavelmente poderia usar a opção gzip -t para testar a integridade dos arquivos

http://linux.about.com/od/commands/l/blcmdl1_gzip.htm

de: http://unix.ittoolbox.com/groups/technical-functional/shellscript-l/how-to-test-file-integrity-of-targz-1138880

Para testar se o arquivo gzip não está corrompido:

gunzip -t file.tar.gz

Para testar se o arquivo tar interno não está corrompido:

gunzip -c file.tar.gz | tar -t > /dev/null

Como parte do backup, você provavelmente poderia apenas executar o último comando e verificar o valor de $? depois, para um valor 0 (sucesso). Se o tar ou o gzip apresentarem um problema, $? terá um valor diferente de zero.

John Boker
fonte
3
E bzip2 -t file.bz2para arquivos bz2.
asmeurer
4
Isso não é apenas usar dois comandos para fazer o que "tar -tzf my_tar.tar.gz> / dev / null" faz?
Rob Wells,
Não deveria ser tar -t > /dev/null(nota: tvs -t)?
Intrastellar Explorer
1
@IntrastellarExplorer que é um erro de digitação da minha parte, embora ainda deva funcionar sem o hífen. Estou acostumado com as opções de estilo antigo do alcatrão. unix.stackexchange.com/questions/394060/…
John Boker
32

Se você quiser fazer uma extração de teste real de um arquivo tar sem extrair para o disco, use a opção -O. Isso lança a extração para a saída padrão em vez do sistema de arquivos. Se o arquivo tar estiver corrompido, o processo será interrompido com um erro.

Exemplo de teste de tarball com falha ...

$ echo "this will not pass the test" > hello.tgz
$ tar -xvzf hello.tgz -O > /dev/null
gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error exit delayed from previous errors
$ rm hello.*

Exemplo de trabalho ...

$ ls hello*
ls: hello*: No such file or directory
$ echo "hello1" > hello1.txt
$ echo "hello2" > hello2.txt
$ tar -cvzf hello.tgz hello[12].txt
hello1.txt
hello2.txt
$ rm hello[12].txt
$ ls hello*
hello.tgz
$ tar -xvzf hello.tgz -O
hello1.txt
hello1
hello2.txt
hello2
$ ls hello*
hello.tgz
$ tar -xvzf hello.tgz
hello1.txt
hello2.txt
$ ls hello*
hello1.txt  hello2.txt  hello.tgz
$ rm hello*
Ossie Moore
fonte
1
Parece-me que o melhor teste é este. Ele realmente extrai cada arquivo e garante que não haja erros.
mangas de
Muito útil. Eu fiz um script de shell, adicione um gancho de argumento para passar o caminho do arquivo e coloque-o no meu caminho :) [tar -xvzf $ 1 -O> / dev / null]
smonff
@sleeves Por que você acha que é melhor do que a resposta aceita? tar -tvzf hello.tgz> / dev / null também dá o mesmo erro.
dash17291
5
@ dash17291 Digo isso porque espero que seja um problema difícil provar que, para todos os casos, um -tvf detectará todos os erros ou corrupções que um -xvf. Em outras palavras, -xvf capturará tudo isso -tvf, mas não posso dizer que o inverso seja verdadeiro.
mangas
Talvez você deva usar > /dev/nullpara o exemplo de trabalho também.
moi
12

Você também pode verificar o conteúdo do arquivo * .tag.gz usando pigz(gzip paralelo) para acelerar a verificação do arquivo:

pigz -cvdp number_of_threads /[...]path[...]/archive_name.tar.gz | tar -tv > /dev/null
ein
fonte
Mini benchmark: executando-o com pigz -cvd: 80s, enquanto executa com a resposta aceita tar -tzv: 143s em um arquivo 22G.
Wadih M.
como você remove a notificação do cronjob sobre "tar: Removendo` / 'principal dos nomes dos membros "ao usar este método?
MaXi32
3

Tentei o seguinte comando e eles funcionam bem.

bzip2 -t file.bz2
gunzip -t file.gz

No entanto, podemos constatar que esses dois comandos são demorados. Talvez precisemos de uma maneira mais rápida de determinar a integridade dos arquivos compactados.

Shicheng Guo
fonte
2

Uma boa opção é usar o tar -tvvf <filePath>que adiciona uma linha que informa o tipo de arquivo.

Exemplo em um arquivo .tar válido:

> tar -tvvf filename.tar 
drwxr-xr-x  0 diegoreymendez staff       0 Jul 31 12:46 ./testfolder2/
-rw-r--r--  0 diegoreymendez staff      82 Jul 31 12:46 ./testfolder2/._.DS_Store
-rw-r--r--  0 diegoreymendez staff    6148 Jul 31 12:46 ./testfolder2/.DS_Store
drwxr-xr-x  0 diegoreymendez staff       0 Jul 31 12:42 ./testfolder2/testfolder/
-rw-r--r--  0 diegoreymendez staff      82 Jul 31 12:42 ./testfolder2/testfolder/._.DS_Store
-rw-r--r--  0 diegoreymendez staff    6148 Jul 31 12:42 ./testfolder2/testfolder/.DS_Store
-rw-r--r--  0 diegoreymendez staff  325377 Jul  5 09:50 ./testfolder2/testfolder/Scala.pages
Archive Format: POSIX ustar format,  Compression: none

Arquivo .tar corrompido:

> tar -tvvf corrupted.tar 
tar: Unrecognized archive format
Archive Format: (null),  Compression: none
tar: Error exit delayed from previous errors.
Diegoreymendez
fonte
Isso ocorre no tar BSD, mas não no tar GNU.
Mcallister de
1

Todas essas são soluções muito abaixo do ideal. Da especificação GZIP

ID2 (IDentificação 2)
Eles têm os valores fixos ID1 = 31 (0x1f, \ 037), ID2 = 139 (0x8b, \ 213), para identificar o arquivo como estando no formato gzip.

Tem que ser codificado em qualquer linguagem que você esteja usando.

Kevin Liu
fonte
se o arquivo foi truncado, isso parece exigir descompressão total para ser detectado
philwalk
0

> use a opção -O. [...] Se o arquivo tar estiver corrompido, o processo será abortado com um erro.

Às vezes sim, mas às vezes não. Vejamos um exemplo de arquivo corrompido:

echo Pete > my_name
tar -cf my_data.tar my_name 

# // Simulate a corruption
sed < my_data.tar 's/Pete/Fool/' > my_data_now.tar
# // "my_data_now.tar" is the corrupted file

tar -xvf my_data_now.tar -O

Isto mostra:

my_name
Fool  

Mesmo se você executar

echo $?

tar disse que não houve erro:

0

mas o arquivo estava corrompido, agora tem "Fool" em vez de "Pete".

Sys
fonte
As pessoas raramente usam arquivos tar sem qualquer compactação. Eu acho que sua observação diz respeito apenas a arquivos não compactados.
Jarekczek de
6
Você está confundindo integridade com corrupção. Seu arquivo perdeu a integridade, mas ainda é um formato de arquivo aceitável.
Phil,