为了解决这个问题,你可以指定 --format gnu:

为了解决这个问题,你可以指定 --format gnu:

我运行了一个测试,从同一个目录创建了两个 tar(其文件保持不变),我发现它们的 md5sum 不同。我假设 tar 的标头中包含了一些时间戳,但我还没有找到覆盖它的方法。我的操作系统是 Ubuntu 9.1。有什么想法吗?

谢谢。

答案1

正如 Dennis 上面指出的那样,它是 gzip。gzip 标头的一部分是文件中压缩内容的 mod 时间。如果您需要 gzip,您可以将 tarfile 作为 tar 之外的额外步骤进行压缩,而不是使用 tar 的内部 gzip。gzip 命令有一个标志来抑制保存该修改时间。

tar -c ./bin |gzip -n >one.tgz
tar -c ./bin |gzip -n >two.tgz
md5sum one.tgz two.tgz

这不会影响 tarfile 内部的时间,只会影响 gzip 标头中的时间。

答案2

要制作具有一致校验和的 tar 文件,只需GZIP=-n像这样添加:

GZIP=-n tar -zcf myOutputTarball.tar /home/luke/directoryIWantToZip

工作原理:Tar 可以使用临时环境变量接受 gzip 选项GZIP,如上所述。正如 Valter 所说,tar 使用 gzip,默认情况下会在存档中放置一个时间戳。这意味着当您压缩相同的文件时,您会得到不同的校验和。该-n选项会禁用该时间戳。

答案3

我也遇到了这个问题,为了让 gzip 不改变时间戳,使用gzip -n

-n, --no-name 不保存或恢复原始名称和时间戳

[valter.silva@alog ~]$ gzip --help
Usage: gzip [OPTION]... [FILE]...
Compress or uncompress FILEs (by default, compress FILES in-place).

Mandatory arguments to long options are mandatory for short options too.

  -c, --stdout      write on standard output, keep original files unchanged
  -d, --decompress  decompress
  -f, --force       force overwrite of output file and compress links
  -h, --help        give this help
  -l, --list        list compressed file contents
  -L, --license     display software license
  -n, --no-name     do not save or restore the original name and time stamp
  -N, --name        save or restore the original name and time stamp
  -q, --quiet       suppress all warnings
  -r, --recursive   operate recursively on directories
  -S, --suffix=SUF  use suffix SUF on compressed files
  -t, --test        test compressed file integrity
  -v, --verbose     verbose mode
  -V, --version     display version number
  -1, --fast        compress faster
  -9, --best        compress better
    --rsyncable   Make rsync-friendly archive

With no FILE, or when FILE is -, read standard input.

Report bugs to <[email protected]>.

例子:

[valter.silva@alog ~]$ ls
renewClaroMMSCanaisSemanal.log.gz  s3

[valter.silva@alog ~]$ gunzip renew.log.gz 
[valter.silva@alog ~]$ gunzip s3/renew.log.gz 

[valter.silva@alog ~]$ md5sum renew.log 
d41d8cd98f00b204e9800998ecf8427e  renew.log

[valter.silva@alog ~]$ md5sum s3/renew.log 
d41d8cd98f00b204e9800998ecf8427e  s3/renew.log

[valter.silva@alog ~]$ gzip -n renew.log 
[valter.silva@alog ~]$ gzip -n s3/renew.log 

[valter.silva@alog ~]$ md5sum renew.log.gz 
7029066c27ac6f5ef18d660d5741979a  renew.log.gz

[valter.silva@alog ~]$ md5sum s3/renew.log.gz 
7029066c27ac6f5ef18d660d5741979a  s3/renew.log.gz

答案4

在其他答案都让我失望之后,我陷入了困境,并设法弄清楚我的 tar 版本(来自 openSUSE 42.3 OSS repo 的 1.27.1)默认使用非确定性pax存档格式,这意味着即使没有压缩(甚至没有明确设置 mtime),使用 tar 从相同文件创建的存档也会有所不同:

$ echo hi > test.file
$ tar --create --to-stdout test.file # long form of `tar cO test.file`
./PaxHeaders.13067/test.file0000644000000000000000000000013213427447703012603 xustar0030 mtime=1549684675.835011178
30 atime=1549684726.410510251
30 ctime=1549684675.835011178
test.file0000644000175000001440000000000313427447703013057 0ustar00hartusers00000000000000hi
$ tar --create --to-stdout test.file
./PaxHeaders.13096/test.file0000644000000000000000000000013213427447703012605 xustar0030 mtime=1549684675.835011178
30 atime=1549684726.410510251
30 ctime=1549684675.835011178
test.file0000644000175000001440000000000313427447703013057 0ustar00hartusers00000000000000hi

请注意,即使没有使用压缩,上面的输出也会有所不同GZIP=-n;未压缩的存档内容(通过对相同内容运行两次 tar 生成)是不同的,因此即使使用其他答案所建议的,压缩内容也会有所不同

为了解决这个问题,你可以指定 --format gnu

$ tar --create --format gnu --to-stdout test.file
test.file0000644000175000001440000000000313427447703011557 0ustar  hartusershi
$ tar --create --format gnu --to-stdout test.file
test.file0000644000175000001440000000000313427447703011557 0ustar  hartusershi

这与上面关于 gzip 的建议一致:

# gzip refuses to write to stdout, so we'll use the `-f` option to create a file
$ GZIP=-n tar --format gnu -czf test.file.tgz test.file && md5sum test.file.tgz
0d8c7b3bdbe8066b516e3d3af60ade75  test.file.tgz
$ GZIP=-n tar --format gnu -czf test.file.tgz test.file && md5sum test.file.tgz
0d8c7b3bdbe8066b516e3d3af60ade75  test.file.tgz

# without GZIP=-n we see a different hash
$ tar --format gnu -czf test.file.tgz test.file && md5sum test.file.tgz
682ce0c8267b90f4103b4c29903c5a8d  test.file.tgz

然而,除了选择比 gzip 更好的压缩格式的正当理由你可能想考虑使用 xz(tar 也支持使用--xz-J标志代替-z),因为它在这里为您节省了一个步骤; 的默认行为是xz在未压缩内容相同时生成相同的压缩输出,因此无需指定如下选项GZIP=-n

$ tar --format gnu --xz -cf test.file.txz test.file && md5sum test.file.txz 
dea99037d4b0ee4565b3639e93ac0930  test.file.txz
$ tar --format gnu --xz -cf test.file.txz test.file && md5sum test.file.txz 
dea99037d4b0ee4565b3639e93ac0930  test.file.txz

相关内容