Como comparar o conteúdo de dois de tarball
-
06-07-2019 - |
Pergunta
Eu quero dizer se dois arquivos tarball contêm arquivos idênticos, em termos de nome de arquivo e conteúdo do arquivo, não incluindo meta-dados, como data, usuário, grupo.
No entanto, existem algumas restrições: em primeiro lugar, eu não tenho controle sobre se a meta-dados são incluídos ao fazer o arquivo tar, na verdade, o arquivo tar sempre contém meta-dados, diff tão diretamente os dois arquivos de alcatrão não funciona. Em segundo lugar, uma vez que alguns arquivos tar são tão grandes que eu não posso dar ao luxo de descompactar-los em um diretório temporário e diff os arquivos contidos um por um. (Eu sei se eu posso file1.tar untar em file1 /, posso compará-los invocando 'tar -dvf file2.tar' no arquivo /. Mas normalmente eu não posso pagar untar até mesmo um deles)
Qualquer idéia de como posso comparar os dois arquivos tar? Seria melhor se ele pode ser realizado dentro de scripts shell. Como alternativa, há alguma maneira de obter soma de verificação de cada sub-arquivo sem um tarball realmente untar?
Obrigado,
Solução
tarsum é quase o que você precisa. Tome a sua saída, executá-lo através tipo de obter a ordenação idêntica em cada um, e então comparar os dois com diff. Isso deve te dar uma implementação básica indo, e seria facilmente o suficiente para puxar esses passos para o programa principal, modificando o código Python para fazer todo o trabalho.
Outras dicas
Você controla a criação desses arquivos tar?
Se assim for, o melhor truque seria a criação de um MD5 checksum e armazená-lo em um arquivo dentro do próprio arquivo. Então, quando você quiser comparar dois arquivos, você acabou de extrair estes arquivos de checksum e compará-los.
Se você pode dar ao luxo de extrato de apenas um arquivo tar , você pode usar a opção --diff
de tar
para procurar diferenças com o conteúdo de outro arquivo tar.
Um truque mais bruto se você está bem com apenas um a comparação dos nomes dos arquivos e seus tamanhos .
Lembre-se, isso não garante que os outros arquivos são os mesmos!
executar um tar tvf
para listar o conteúdo de cada arquivo e armazenar as saídas em dois arquivos diferentes. em seguida, fatia para fora tudo além das colunas de nome de arquivo e tamanho. De preferência, tipo os dois arquivos também. Então, basta fazer uma diff arquivo entre as duas listas.
Apenas lembre-se que este último regime não realmente soma de verificação.
tar amostra e saída (todos os arquivos são de tamanho zero neste exemplo).
$ tar tvfj pack1.tar.bz2
drwxr-xr-x user/group 0 2009-06-23 10:29:51 dir1/
-rw-r--r-- user/group 0 2009-06-23 10:29:50 dir1/file1
-rw-r--r-- user/group 0 2009-06-23 10:29:51 dir1/file2
drwxr-xr-x user/group 0 2009-06-23 10:29:59 dir2/
-rw-r--r-- user/group 0 2009-06-23 10:29:57 dir2/file1
-rw-r--r-- user/group 0 2009-06-23 10:29:59 dir2/file3
drwxr-xr-x user/group 0 2009-06-23 10:29:45 dir3/
comando para gerar nome ordenada / list tamanho
$ tar tvfj pack1.tar.bz2 | awk '{printf "%10s %s\n",$3,$6}' | sort -k 2
0 dir1/
0 dir1/file1
0 dir1/file2
0 dir2/
0 dir2/file1
0 dir2/file3
0 dir3/
Você pode tomar duas dessas listas ordenadas e diff-los.
Você também pode usar os de data e hora colunas se isso funciona para você.
pkgdiff para visualizar as diferenças entre pacotes (detecta adicionadas / removidas / arquivos renomeados e conteúdo alterado, existir com código zero se inalterado):
pkgdiff PKG-0.tgz PKG-1.tgz
Aqui está a minha variante, está verificando a permissão unix demasiado:
só funciona se os nomes de arquivos são mais curtos do que 200 caracteres.
diff <(tar -tvf 1.tar | awk '{printf "%10s %200s %10s\n",$3,$6,$1}'|sort -k2) <(tar -tvf 2.tar|awk '{printf "%10s %200s %10s\n",$3,$6,$1}'|sort -k2)
Eu percebo que esta é uma resposta tardia, mas me deparei com o fio enquanto tenta conseguir a mesma coisa. A solução que eu tenho implementado saídas do tar para stdout, e tubos para qualquer hash de que você escolher:
tar -xOzf archive.tar.gz | sort | sha1sum
Note que a ordem dos argumentos é importante; particularmente O
qual os sinais de uso stdout.
Tardiff o que você está procurando? É "um script Perl simples" que "compara o conteúdo de dois tarballs e relatórios sobre eventuais diferenças encontradas entre eles."
Se não extrair os arquivos nem precisar as diferenças, tente diff 's q opção:
diff -q 1.tar 2.tar
Este tranquila resultado será "1.tar 2.tar diferem" ou nada, se há diferenças.
Há ferramenta chamada archdiff . É basicamente um script Perl que pode olhar para os arquivos.
Takes two archives, or an archive and a directory and shows a summary of the
differences between them.
Eu tenho uma pergunta semelhante e eu resolvê-lo por python, aqui está o código. ps: embora este código é usado para comparar o conteúdo de dois de zipball, mas é semelhante com tarball, espero que eu possa ajudá-lo
import zipfile
import os,md5
import hashlib
import shutil
def decompressZip(zipName, dirName):
try:
zipFile = zipfile.ZipFile(zipName, "r")
fileNames = zipFile.namelist()
for file in fileNames:
zipFile.extract(file, dirName)
zipFile.close()
return fileNames
except Exception,e:
raise Exception,e
def md5sum(filename):
f = open(filename,"rb")
md5obj = hashlib.md5()
md5obj.update(f.read())
hash = md5obj.hexdigest()
f.close()
return str(hash).upper()
if __name__ == "__main__":
oldFileList = decompressZip("./old.zip", "./oldDir")
newFileList = decompressZip("./new.zip", "./newDir")
oldDict = dict()
newDict = dict()
for oldFile in oldFileList:
tmpOldFile = "./oldDir/" + oldFile
if not os.path.isdir(tmpOldFile):
oldFileMD5 = md5sum(tmpOldFile)
oldDict[oldFile] = oldFileMD5
for newFile in newFileList:
tmpNewFile = "./newDir/" + newFile
if not os.path.isdir(tmpNewFile):
newFileMD5 = md5sum(tmpNewFile)
newDict[newFile] = newFileMD5
additionList = list()
modifyList = list()
for key in newDict:
if not oldDict.has_key(key):
additionList.append(key)
else:
newMD5 = newDict[key]
oldMD5 = oldDict[key]
if not newMD5 == oldMD5:
modifyList.append(key)
print "new file lis:%s" % additionList
print "modified file list:%s" % modifyList
shutil.rmtree("./oldDir")
shutil.rmtree("./newDir")
Há também diffoscope é, o que é mais genérico, e permite comparar as coisas de forma recursiva (incluindo vários formatos).
pip install diffoscope
Pode-se usar um script simples:
#!/usr/bin/env bash
set -eu
tar1=$1
tar2=$2
shift 2
tar_opts=("$@")
tmp1=`mktemp -d`
_trap="rm -r "$tmp1"; ${_trap:-}" && trap "$_trap" EXIT
tar xf "$tar1" -C "$tmp1"
tmp2=`mktemp -d`
_trap="rm -r "$tmp2"; ${_trap:-}" && trap "$_trap" EXIT
tar xf "$tar2" -C "$tmp2"
diff -ur "${tar_opts[@]:+${tar_opts[@]}}" "$tmp1" "$tmp2"
Uso:
diff-tars.sh TAR1 TAR2 [DIFF_OPTS]