为什么解压缩此tgz会在我的Mac而不是Linux上引发错误?


27

我遇到了一个很奇怪的问题,无法弄清楚是怎么回事。我有一个tgz文件scip-3.2.0.tgz,当我尝试解压缩该文件时会抛出错误。该错误仅在OS X上发生(我在10.10.4上)。我可以在运行CentOS 6.6的Linux机器上无错误地提取文件。当同时使用命令行tar命令和使用归档实用程序时,将发生错误。我通过电子邮件发送了SCIP邮件列表,并且与其他用户(e085a4a3591eddf945dcb365d97d2512c267e374)具有相同的SHA-1哈希,因此没有下载错误。他们不确定发生了什么。

这是我尝试使用归档实用程序解压缩时遇到的错误:

存档实用程序错误

万一图像损坏了,图像中的文字会这样写:

无法将“ scip-3.2.0.tgz”扩展到“桌面”。
(错误1-不允许操作。)

当我尝试通过命令行解压缩时,这就是我得到的输出。这是与tar: Error exit delayed from previous errors.我有关的最后一行()。我看不出是什么原因造成的。归档文件似乎没有问题,但我不信任它并抛出该错误。

有谁知道是什么原因造成的?

[edit]
仔细观察输出,第1108行包含错误:

x scip-3.2.0/applications/Coloring/Makefile: Can't create 'scip-3.2.0/applications/Coloring/Makefile'

2
它可以与非存档程序之类的其他应用程序一起使用吗?wakaba.c3.cx/s/apps/unarchiver.html
TryTryAgain

是的,它确实!我想知道他们在做些什么。问题的一部分是我有一个bash脚本,可以自动执行很多操作,它需要做的一件事情就是提取此tgz,以便它可以构建其中的内容。我不知道是否有在一个错误tar附带OS X的命令
杰夫·

1
很可能有一个错误。我发现内置的OS X存档实用程序非常糟糕。您无法将所需的文件重新存档为zip或其他内容吗?另外,如果您正在编写脚本,那么gunzip -c scip-3.2.0.tgz | tar xopf -从命令行使用该脚本时是否还会发生该错误?
TryTryAgain

是的,该命令会引发相同的错误。gunzip效果很好,但是当我尝试提取未压缩的tarball时,就会抛出错误。
杰夫2015年

啊,原来压缩包确实有错误!我没疯。我会写一个更详细的答案。显然,OS X中的tar实用工具在这里是正确的!
杰夫2015年

Answers:


32

这应该有助于确定Johnny的答案中发生了什么,以及回答为什么它在Linux上而不在Mac上有效的问题。

问题在于Mac OS X使用了事实bsdtar,而大多数Linux系统使用了事实gnutar

您可以gnutar使用brew install gnu-tar,在带有Homebrew的Mac上进行安装,该符号将链接gnutar/usr/local/binas gtar

如果安装gnutar,则可以使用Johnny's answer中的步骤重现该问题。

$ brew install gnu-tar
==> Downloading https://homebrew.bintray.com/bottles/gnu-tar-1.28.yosemite.bottle.2.tar.gz
######################################################################## 100.0%
==> Pouring gnu-tar-1.28.yosemite.bottle.2.tar.gz
==> Caveats
gnu-tar has been installed as "gtar".

If you really need to use it as "tar", you can add a "gnubin" directory
to your PATH from your bashrc like:

    PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"
==> Summary
🍺  /usr/local/Cellar/gnu-tar/1.28: 13 files, 1.6M
$ mkdir test
$ touch test/a test/b
$ gtar -zcvf test.tar.gz test test/a # make the archive with gnutar
test/
test/a
test/b
test/a
$ gtar -ztvf test.tar.gz
drwxr-xr-x adamliter/staff   0 2015-07-28 22:41 test/
-rw-r--r-- adamliter/staff   0 2015-07-28 22:41 test/a
-rw-r--r-- adamliter/staff   0 2015-07-28 22:41 test/b
hrw-r--r-- adamliter/staff   0 2015-07-28 22:41 test/a link to test/a
$ rm -r test
$ tar -xvf test.tar.gz # try to unpack the archive with bsdtar
x test/
x test/a
x test/b
x test/a: Can't create 'test/a'
tar: Error exit delayed from previous errors.
$ echo $?
1

因此,很显然,将内容gnutar归档的方式会导致bsdtar重复项阻塞。gtar -ztvf test.tar.gz令人鼓舞的是,将的第二个实例test/a存档为a 的事实link to test/a是相关的。正如Johnny在评论中指出的那样,gnutar会将重复项存储为硬链接,而不是实际文件,可以使用禁用该链接--hard-dereference

也就是说,您可以执行以下操作:

$ mkdir test
$ touch test/a test/b
$ gtar -zcvf test.tar.gz test test/a --hard-dereference
test/
test/a
test/b
test/a
$ gtar -ztvf test.tar.gz test
drwxr-xr-x adamliter/staff   0 2015-07-28 23:49 test/
-rw-r--r-- adamliter/staff   0 2015-07-28 23:49 test/a
-rw-r--r-- adamliter/staff   0 2015-07-28 23:49 test/b
-rw-r--r-- adamliter/staff   0 2015-07-28 23:49 test/a # note that this is no longer a link
$ rm -r test
$ tar -xvf test.tar.gz # unpack with bsdtar
x test/
x test/a
x test/b
x test/a
$ echo $?
0
$ ls test/
a b

但是,在这种情况下,您显然无法控制tarball的创建,因此--hard-dereference不是一种选择。幸运的是,基于OP的回答,似乎这个问题已由上游解决。

但是,如果将来还有其他人遇到此问题,并且需要快速修复或对上游维护人员没有响应,则可以采取解决方法。

一旦确定了重复文件是什么,就可以使用--fast-read选项bsdtar(请注意,该选项仅是的一部分bsdtar而不是 gnutar):

 -q (--fast-read)
         (x and t mode only) Extract or list only the first archive entry that matches each pattern or filename operand.  Exit as soon as each specified pat-
         tern or filename has been matched.  By default, the archive is always read to the very end, since there can be multiple entries with the same name
         and, by convention, later entries overwrite earlier entries.  This option is provided as a performance optimization.

因此,在我按照约翰尼的答案中的玩具示例创建的玩具示例中,重复文件为test/a。因此,您可以通过执行以下操作来避免此问题:

# this set of commands picks up from the first set of commands
# i.e., the following assumes a tarball that was *not* made with
# the --hard-dereference option, although this will work just as well
# with one that was
$ tar -xvqf test.tar.gz test/a # unarchive the first instance of test/a
x test/a
$ tar -xvf test.tar.gz --exclude test/a # unarchive everything except test/a
x test/
x test/b
$ echo $?
0
$ ls test/
a b

请注意,此外,gnutar即使--hard-dereference不使用该选项,也很高兴用自己创建的重复文件解压缩存档:

$ rm -r test
$ gtar -xvf test.tar.gz
test/
test/a
test/b
test/a
$ echo $?
0
$ ls test/
a b

因此,这回答了您关于为什么在Mac而不是Linux上引发错误的问题。(大多数)Linux发行版附带gnutar,并且由于tarball大概是打包在一起的gnutar,因此,在打开打包时不会有错误gnutar,但是在打开打包时会出错bsdtar


为了进一步阅读和参考,您可能想看看bsdtar和GNU tar有什么区别?在Unix.SE上。


哇,很好听,我不知道gnutar和bsd焦油之间有什么显着差异。基于您的gtar -tcvf,gnutar足够“聪明”,可以优化第二个副本文件作为链接,而不是将其复制到存档中。
约翰尼

搜寻文档后,这似乎是gtar硬链接处理的副作用。似乎认为重复的文件实际上是该文件的硬链接,因此将其存储为链接而不是实际文件。为gtar提供--hard-dereference选项会禁用此行为。
约翰尼

@Johnny确实是这两个Homebrew维护者(Misty De Meo和Dominyk Tiller)解决了这个问题。我使用的某些软件的维护者发布了一个新版本的压缩包中有一个重复的文件,这在尝试用Homebrew安装新版本时引起了问题(显然)。无论如何,感谢您检查文档!我将其添加到答案中。
亚当·里特(Adam Liter)2015年

太好了 我将其标记为答案,因为它是对所发生情况的最彻底的解释。谢谢!
杰夫2015年

7

存档中重复文件的存在不应使其无效或无法在OSX上提取,因为tar默认会覆盖重复项。

所以,我在你的要点行为弄得有点- OSX焦油允许在存档(倒退到其原来的目的的重复文件牛逼AR韭菜实用,因此它允许文件附加到年底磁带存档,还原存档后,文件的最新版本将覆盖旧版本)

只有当出现“ -k”选项时,tar才应警告预先存在的文件。

在这里,我创建了一个包含重复文件的档案,然后毫无问题地将其提取。直到我添加了-k选项,它才警告我有关重复文件的信息:

Macbook> tar --version
bsdtar 2.8.3 - libarchive 2.8.3
Macbook> mkdir test
Macbook> touch test/a test/b
Macbook> tar -zcvf test.tar.gz test test/a
a test
a test/a
a test/b
a test/a
Macbook> tar -ztvf test.tar.gz
drwxr-xr-x  0 user group       0 Jul 28 10:42 test/
-rw-r--r--  0 user group       0 Jul 28 10:42 test/a
-rw-r--r--  0 user group       0 Jul 28 10:42 test/b
-rw-r--r--  0 user group       0 Jul 28 10:42 test/a
Macbook> rm -r test
Macbook> tar -xvf test.tar.gz
x test/
x test/a
x test/b
x test/a
Macbook> echo $?
0
Macbook> rm -r test
Macbook> tar -k -xvf test.tar.gz
x test/
x test/a
x test/b
x test/a: Already exists
tar: Error exit delayed from previous errors.
Macbook> echo $?
1

一个简单的umask问题似乎也不是罪魁祸首,我尝试将umask更改为0777,但仍然可以提取存档:

Macbook> tar -xvf test.tar
x test/
x test/a
x test/b
x test/a
Macbook> ls -l test
ls: test: Permission denied
Macbook> sudo ls -l test
total 0
----------  1 someuser  wheel  0 Jul 28 13:48 a
----------  1 someuser  wheel  0 Jul 28 13:48 b

我以为我可以通过故意将不可写的目录添加到存档中来复制该问题,但这是行不通的,tar在提取存档时未更新目录的权限:

Macbook> mkdir -p testdir1/test testdir2/test
Macbook> touch testdir1/test/{a,b} testdir2/test/a
Macbook> chmod -w testdir2/test
Macbook> touch testdir2/test/b
touch: testdir2/test/b: Permission denied
Macbook> find testdir* -ls  | awk '{print $3, $11}'
drwxrwx--- testdir1
drwxrwx--- testdir1/test
-rw-rw---- testdir1/test/a
-rw-rw---- testdir1/test/b
drwxrwx--- testdir2
dr-xr-x--- testdir2/test
-rw-rw---- testdir2/test/a
Macbook> cd testdir1
Macbook> tar -cvf ../test.tar test/*
a test/a
a test/b
Macbook> cd ../testdir2
Macbook> tar -rvf ../test.tar test
a test
a test/a
Macbook> cd ..
Macbook> tar -tvf ./test.tar
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/a
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/b
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/a
dr-xr-x---  0 username groupname       0 Jul 28 15:40 test/
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/a
Macbook> tar -xvf test.tar
x test/a
x test/b
x test/a
x test/
x test/a
Macbook> 

我还尝试将test / a的权限更改为000,将其附加到存档中,然后附加另一个test / a,但该方法也可以正常工作:

drwxrwx---  0 username groupname       0 Jul 28 15:40 test/
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/a
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/b
dr-xr-x---  0 username groupname       0 Jul 28 15:40 test/
----------  0 username groupname       0 Jul 28 15:40 test/a
-rw-rw----  0 username groupname       0 Jul 28 15:40 test/a

因此,我真的很想查看导致该问题的原始存档,并查看该存档中可能导致该问题的内容。

如果文件名和目录共享相同的名称,则tar提取时确实有问题,但是它有一条非常清晰的错误消息:

Macbook> tar -xvf test.tar
x test/
x test/dir1/
x test/dir1/a
x test/
x test/dir1: Can't remove already-existing dir
tar: Error exit delayed from previous errors.

(如果冲突是相反发生的,即先出现一个文件,然后再出现一个具有相同名称的目录,那么tar只会删除它并创建目录:

Macbook> tar -xvf test.tar
x test/
x test/dir1
x test/
x test/dir1/
x test/dir1/a

1
我更清楚地表明,由于tar档案中允许文件重复,因此他的要点(和他的自我回答)中的行为似乎不是完整的答案。因此,“我无法使用重复的文件解压缩tar归档文件”的答案不应为“删除重复的文件”,因为tar应该能够处理这种情况。
约翰尼

2
这确实是一条评论-它没有提供解决方案,仅是在现有解决方案上的讨论。约翰尼,您可以将其移至评论吗?我会稍后再删除它,只是想让您有机会先将其移动。谢谢。
伊恩·C(

2
@Johnny,此信息确实具有超有价值的信息,但这不是问题的答案。这是对另一个答案的评论。这样想:如果Geoff的答案被删除,这个答案有用吗?不,不会。确实,此答案的内容是“ Geoff的其他答案似乎不正确”。最初的问题是“什么导致此错误?” 您最能回答的问题是“我不知道是什么原因造成的,但这不是重复的文件”-但这需要进行编辑,但仍然无法真正回答原始问题。
DW

2
我希望这不会被删除,因为从更大的角度来看,这是一个学习的地方,而本文中的详细信息是IMO一流的。+1且无需删除-我认为这将帮助处于类似情况的其他用户找到没有OP损坏文件或损坏交互不同的东西,不是吗?
bmike

2
@bmike和其他人:我添加了一个答案该答案至少应该解释这里发生了什么,尽管不一定是为什么。
亚当·里特(Adam Liter)2015年

6

原来OS X tar实用程序是正确的!存档中确实存在错误。该电子邮件线程对其进行了详细讨论,但问题是存档存在重复文件。在我键入此内容时,SCIP专家正在修复存档。

[edit]
新更新的scip-3.2.0.tgz现在可以正常提取了!新tgz的SHA-1哈希为5b4e8283f4a5bf9e50f9a62d4320d6f5f50c8476

[edit 2]
并不是存档中有错误。仅仅是bsdtarOS X gnutar附带的,与Linux附带的处理重复文件的方式不同。@Adam Liter 在这里的答案提供了正在发生的事情的详尽解释。


1
有趣。因此,也许其他实用程序会忽略重复文件错误并继续前进而不会抱怨?无论如何,很高兴您找到了原因和答案。
TryTryAgain

1
是的,我认为这正是其他实用程序正在做的事情。我认为OS X tar实用程序是正确的选择。格式错误的存档应始终至少发出警告,以警告用户某些问题。谢谢你的帮助!
杰夫

tar归档文件中的重复文件不会使它成为格式错误的归档文件,tar格式专门允许重复。我很好奇为什么您的Mac tar拒绝解压缩档案,即使您没有指定该-k选项,也会使它警告已存在的文件。不幸的是,他们已经更新了scip-3.2.0.tgz文件以删除重复项,因此我无法测试该存档。
约翰尼

tar提取物不同的反应,在试图提取scip-3.2.0/applications/Coloring/Makefile两次,这取决于你的umask。如果第一个创建的对象没有留下写访问权限,则第二个尝试将失败。
2015年

1
@DW我添加了一个答案,解释了为什么这不是矛盾。
亚当·里特(Adam Liter)2015年

1

我为Mac OSX使用了另一种免费的轻量级存档软件。它叫做Keka,我最专门用它解压缩7zip。此外,它还可以解压缩其他类型的文件,如.rar,.tar,.gz等。它也适用于OP的特定tar文件,但是在@Geoff提到该团队正在修复文件之后,我尝试了它。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.