创build一个包含校验和的tar文件

这是我的问题:我需要存档大量的文件(高达60TB)的大文件(通常每个30到40GB)。 我想在归档之前对这些文件进行校验和(md5,sha1,不pipe) 然而, 不是每次读取文件两次(一次是校验和,两次是tar'ing)对于实现非常高的归档性能(LTO-4希望持续120MB /秒,而备份窗口是有限的)或多或less是必要的。

所以我需要一些方法来读取一个文件,一边提供一个校验和工具,另一边build立一个焦油到磁带,一些东西:

tar cf - files | tee tarfile.tar | md5sum - 

除了我不希望整个存档的校验和(这个示例shell代码就是这样做),而是存档中每个单独文件的校验和。

我研究过GNU tar,Pax,Star选项。 我看了Archive :: Tar的来源。 我没有看到明显的办法来实现这一目标。 看起来我必须用C或类似的方法来构build一些东西来实现我所需要的东西。 Perl / Python /等不会削减它的性能,各种焦油程序错过了必要的“插件架构”。 有没有人知道任何现有的解决scheme之前,我开始代码搅动?

在继续并重新编写tar之前,您可能需要简要介绍两次读取数据的快捷方法,因为它可能不会比单次执行要慢很多。

两种方法在这里被实现:

http://www.g-loaded.eu/2007/12/01/veritar-verify-checksums-of-files-within-a-tar-archive/

与单行:

  tar -cvpf mybackup.tar myfiles/| xargs -I '{}' sh -c "test -f '{}' && md5sum '{}'" | tee mybackup.md5 

虽然md5sum正在从磁盘读取每个文件,而不是通过pipe道读取数据,而是通过pipe道传输数据,但是Linux磁盘caching应该使得从存储器缓冲区读取一个简单的读数,这应该不会慢于stdin读取。 您只需确保磁盘高速caching中有足够的空间来存储第二个阅读器始终从caching中读取的每个文件的足够空间,并且远远不够,无法从磁盘检索

这是一个Python脚本示例。 它计算文件的校验和作为被添加到档案中。 在脚本结尾处,校验和文件被添加到存档中。

 import hashlib,os import tarfile def md5(filename): ''' function to get md5 of file ''' d = hashlib.md5() try: d.update(open(filename).read()) except Exception,e: print e else: return d.hexdigest() root="/home" outtar=os.path.join(root,"path1","output.tar") path = os.path.join(root,"path1") chksum_file=os.path.join(root,"path","chksum.txt") tar = tarfile.open(outtar, "w") o_chksum=open(chksum_file,"w") for r,d,f in os.walk(path): for files in f: filename=os.path.join(r,files) digest="%s:%s"%(md5(filename) , filename) o_chksum.write(digest+"\n") tar.add(os.path.join(r,files)) tar.add(chksum_file) tar.close() o_chksum.close() 

当你解压时,使用chksum_file来validation校验和

我认为你的问题是tar的devise问题,因为tar不允许通过内容表在存档文件中进行随机访问/定位,因此所有协议都是文件而不是基于缓冲区。
因此,您可以查看不同的格式,例如允许随机访问的PAX或DAR。

最近的档案格式通常包括一些用于文件validation的散列,但是它们也有类似的问题:你不能总是select你自己的散列函数,也不能保存散列的本地副本。

您可能希望保存散列的本地副本,与embedded存档本身的本地副本不同:例如,如果存档脱机存储(在磁带或读取数据的数据中心上),并且要validation本地副本的文件/目录。

7zip有几个选项,如7z h与自定义散列和7z l -slt列出所有的散列和7z l -slt ,但是如果你想要一个md5或sha1散列列表? 您可以使用-bb-bs来控制冗长, -bs用接受的答案中提到的George Notaras方法:

 7z a -bsp1 -bb3 dir.7z dir 2>&1 \ | grep "^+" | sed 's,^+ ,,g' | xargs -d "\n" -I § -P 1 sh -c "test -f '§' && sha1sum '§'" \ | tee dir.sha1