Por que o gzip na saída tar sempre produz resultados diferentes?

5

O que eu espero de dois comandos que sempre produzem a mesma saída sozinhos é que eles sempre produzam a mesma saída quando colocados em um pipeline, mas aparentemente esse não é o caso de tar | gzip :

~/test$ ls
~/test$ dd if=/dev/urandom of=file bs=10000000 count=1
1+0 records in
1+0 records out
10000000 bytes (10 MB) copied, 0,877671 s, 11,4 MB/s // Creating a 10MB random file
~/test$ tar cf file.tar file // Archiving the file in a tarball
~/test$ tar cf file1.tar file // Archiving the file again in another tarball
~/test$ cmp file.tar file1.tar // Comparing the two output files
~/test$ gzip -c file > file.gz // Compressing the file with gzip
~/test$ gzip -c file > file1.gz // Compressing the file again with gzip
~/test$ cmp file.gz file1.gz // Comparing the two output files
~/test$ tar c file | gzip > file.tar.gz // Archiving and compressing the file
~/test$ tar c file | gzip > file1.tar.gz // Archiving and compressing the file again
~/test$ cmp file.tar.gz file1.tar.gz // Comparing the output files
file.tar.gz file1.tar.gz differ: byte 5, line 1 // File differs at byte 5
~/test$ cmp -i 5 file.tar.gz file1.tar.gz // Comparing the output files after byte 5
~/test$ 

Além disso, até tar cfz file.tar file por conta própria sempre produz resultados diferentes:

~/test$ tar cfz file2.tar file // Archiving and compressing the file
~/test$ tar cfz file3.tar file // Archiving and compressing the file again
~/test$ cmp file2.tar.gz file3.tar.gz // Comparing the output files
file2.tar.gz file3.tar.gz differ: byte 5, line 1 // File differs at byte 5
~/test$ cmp -i 5 file2.tar.gz file3.tar.gz // Comparing the output files after byte 5
~/test$ 

Enquanto a divisão do pipeline finalmente produz uma saída que faz sentido:

~/test$ gzip -c file.tar > file4.tar.gz
~/test$ gzip -c file.tar > file5.tar.gz
~/test$ cmp file4.tar.gz file5.tar.gz 
~/test$ 

Parece que o que acontece acontece somente quando a saída de tar é canalizada diretamente para gzip .

Qual é a explicação deste comportamento?

    
por kos 20.02.2015 / 13:47

2 respostas

8

O cabeçalho do arquivo gzip resultante é diferente dependendo de como é chamado.

O Gzip tenta armazenar algumas informações de origem no cabeçalho do arquivo resultante. Quando chamado em arquivos normais, isso inclui o nome do arquivo de origem por padrão e um registro de data e hora, que ele obtém do arquivo original.

Quando é feito para compactar os dados enviados para ele, a origem não é tão fácil quanto com um arquivo normal, por isso recorre a uma convenção diferente de nomenclatura e registro de data e hora.

Para provar isso, adicione o -n param às linhas problemáticas em seu exemplo como ...

~/temp$ tar c file | gzip -n > file1.tar.gz
~/temp$ tar c file | gzip -n > file.tar.gz
~/temp$ cmp file.tar.gz file1.tar.gz

Agora os arquivos são idênticos novamente ...

De man gzip ...

   -n --no-name
          When  compressing,  do  not save the original file name and time
          stamp by default. (The original name is always saved if the name
          had  to  be  truncated.)  When decompressing, do not restore the
          original file name if present (remove only the gzip suffix  from
          the  compressed  file name) and do not restore the original time
          stamp if present (copy it from the compressed file). This option
          is the default when decompressing.

Portanto, a diferença é, na verdade, o nome do arquivo original e a informação de registro de data e hora que é desativada pelo parâmetro -n.

    
por Clayton Mills 20.02.2015 / 15:09
5

Os arquivos Gzip incluem um registro de data e hora. Se você criar dois arquivos gzip em momentos diferentes, eles serão diferentes pelo tempo de criação, não pelo conteúdo.

    
por Andrea Corbellini 20.02.2015 / 13:52

Tags