Pourquoi extraire ce tgz génère-t-il une erreur sur mon Mac mais pas sur Linux?

27

Je rencontre un problème assez étrange et je n'arrive pas à comprendre ce qui se passe. J'ai un fichier tgz, scip-3.2.0.tgz , qui génère une erreur lorsque je tente de le décompresser. L'erreur ne se produit que sur OS X (je suis sur 10.10.4). Je peux extraire le fichier sans erreur sur une boîte Linux exécutant CentOS 6.6. L'erreur se produit lorsque vous utilisez à la fois la commande de ligne de tarcommande et lorsque vous utilisez l'utilitaire d'archivage. J'ai envoyé la liste de diffusion SCIP par e-mail et j'ai le même hachage SHA-1 qu'un autre utilisateur ( e085a4a3591eddf945dcb365d97d2512c267e374), il n'y a donc pas eu d'erreur de téléchargement. Ils ne savent pas ce qui se passe.

Voici l'erreur que j'obtiens lorsque j'essaie de décompresser à l'aide de l'utilitaire d'archivage:

erreur de l'utilitaire d'archivage

Dans le cas où l'image est cassée, le texte de l'image dit ceci:

Impossible de développer "scip-3.2.0.tgz" en "Bureau".
(Erreur 1 - Opération non autorisée.)

Et lorsque j'essaie de décompresser via la ligne de commande, c'est la sortie que j'obtiens . C'est la dernière ligne ( tar: Error exit delayed from previous errors.) qui me concerne. Je ne vois pas ce qui en est la cause. L'archive semble s'extraire sans problème, mais je ne lui fais pas confiance avec cette erreur lancée.

Est-ce que quelqu'un sait ce qui cause cela?

[edit]
En regardant de plus près la sortie, la ligne 1108 contient l'erreur:

x scip-3.2.0/applications/Coloring/Makefile: Can't create 'scip-3.2.0/applications/Coloring/Makefile'
Geoff
la source
2
Cela fonctionne-t-il avec une autre application comme le désarchiveur? wakaba.c3.cx/s/apps/unarchiver.html
TryTryAgain
Oui! Je me demande ce qu'ils font différemment. Une partie du problème est que j'ai un script bash qui automatise un tas de choses, et l'une des choses qu'il doit faire est d'extraire ce tgz afin qu'il puisse construire ce qu'il contient. Je me demande s'il y a un bug dans la tarcommande livrée avec OS X.
Geoff
1
Très probablement, il y a un bug. J'ai trouvé que l'utilitaire d'archivage OS X intégré était assez merdique. N'y a-t-il aucun moyen de ré-archiver les fichiers nécessaires dans un zip ou quelque chose? De plus, si vous le scriptez, l'erreur se produit-elle également lorsque vous êtes en gunzip -c scip-3.2.0.tgz | tar xopf -ligne de commande, comme vous l'utiliseriez pour votre script?
TryTryAgain
Ouais, cette commande renvoie la même erreur. gunzipfonctionne très bien, mais lorsque j'essaie d'extraire l'archive non compressée, c'est à ce moment que l'erreur est renvoyée.
Geoff
Ah, il s'avère qu'il y avait bien une erreur dans l'archive! Je ne suis pas fou. Je rédigerai une réponse plus détaillée. Apparemment, l'utilitaire tar sous OS X était le bon ici!
Geoff

Réponses:

32

Cela devrait aider à identifier ce qui se passe dans la réponse de Johnny , ainsi qu'à répondre à la question de savoir pourquoi cela fonctionne sur Linux mais pas sur Mac.

Le problème réside dans le fait que Mac OS X utilise bsdtar, alors que la plupart des systèmes Linux utilisent gnutar.

Vous pouvez installer gnutarsur un Mac avec Homebrew, en utilisant brew install gnu-tar, qui sera un lien symbolique gnutarvers /usr/local/binas gtar.

Si vous installez gnutar, vous pouvez reproduire le problème en suivant les étapes de la réponse de Johnny .

$ 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

Il est donc évident que les gnutarchoses sont archivées différemment d'une manière qui provoque l' bsdtarétouffement des doublons. Le fait qui gtar -ztvf test.tar.gzindique que la deuxième instance de test/aest archivée en tant que link to test/aest pertinent. Comme Johnny le souligne dans les commentaires, gnutarstockera les doublons sous forme de liens physiques plutôt que le fichier réel, qui peut être désactivé avec --hard-dereference.

Autrement dit, vous pouvez effectuer les opérations suivantes:

$ 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

Cependant, dans ce cas, vous ne contrôlez évidemment pas la création de l'archive tar, ce --hard-dereferencen'est donc pas une option. Heureusement, sur la base de la réponse du PO , il semble que ce problème ait été résolu par l'amont.

Néanmoins, si quelqu'un d'autre rencontre ce problème à l'avenir et a besoin d'une solution rapide ou a un responsable en amont qui ne répond pas, il existe une solution de contournement.

Une fois que vous avez identifié le fichier en double, vous pouvez utiliser l' --fast-readoption de bsdtar(notez que cette option n'est qu'une partie de bsdtar, pas 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.

Ainsi, dans l'exemple de jouet que j'ai créé à la suite de l'exemple de jouet dans la réponse de Johnny , le fichier en double est test/a. Ainsi, vous pouvez éviter ce problème en procédant comme suit:

# 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

Notez, en outre, que gnutarvous êtes parfaitement heureux de décompresser une archive avec des doublons qui a été créée par elle-même, même lorsque l' --hard-dereferenceoption n'a pas été utilisée:

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

Cela répond donc à votre question de savoir pourquoi une erreur est lancée sur Mac mais pas Linux. (La plupart) des distributions Linux sont livrées avec gnutar, et comme l'archive tar était vraisemblablement empaquetée avec gnutar, il n'y aura pas d'erreur lors du déballage avec gnutar, mais il y aura une erreur lors du déballage avec bsdtar.


Pour plus de lecture et de référence, on pourrait vouloir regarder quelles sont les différences entre bsdtar et GNU tar? sur Unix.SE.

Adam Liter
la source
Wow, beau détective, je ne savais pas qu'il y avait une différence significative entre gnutar et bsd tar. Sur la base de votre gtar -tcvf, gnutar est suffisamment "intelligent" pour optimiser le deuxième fichier de copie sous forme de lien au lieu de le dupliquer dans l'archive.
Johnny
Après avoir parcouru les documents, il semble que ce soit un effet secondaire de la gestion des liens durs de gtar. Il semble penser que le fichier en double est en fait un lien dur vers le fichier, il le stocke donc en tant que lien au lieu du fichier réel. Donner gtar l' --hard-dereferenceoption désactive ce comportement.
Johnny
@Johnny Ce sont vraiment deux des responsables de Homebrew qui ont compris cela (Misty De Meo et Dominyk Tiller). Un responsable de certains logiciels que j'utilise a publié une nouvelle version avec un fichier en double dans l'archive tar, ce qui a causé des problèmes lors de la tentative d'installation de la nouvelle version avec Homebrew (évidemment). Quoi qu'il en soit, merci d'avoir consulté les documents! J'ajouterai cela à la réponse.
Adam Liter
C'est excellent. Je marque cette réponse comme étant l'explication la plus complète de ce qui se passe. Merci!
Geoff
7

L'existence d'un fichier en double dans l'archive ne doit pas le rendre invalide ou impossible à extraire sur OSX, car par défaut, tar écrase les doublons.

Donc, je suis un peu confus par le comportement dans votre Gist - tar OSX permet pour les fichiers en double dans une archive (un retour à son objectif initial en tant que t singe ar civette utilitaire, il permet aux fichiers à ajouter à la fin de l'archive sur bande, et lorsque l'archive est restaurée, la dernière version du fichier remplacera la ou les anciennes versions)

Ce n'est que lorsque l'option "-k" est présente que tar doit avertir des fichiers préexistants.

Ici, j'ai créé une archive avec un fichier en double puis je l'ai extraite sans problème. Ce n'est que lorsque j'ai ajouté l'option -k qu'elle m'a averti du fichier en double:

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

Un simple problème umask ne semble pas être le coupable non plus, j'ai essayé de changer mon umask en 0777 et je peux toujours extraire l'archive:

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

Je pensais que je pouvais dupliquer le problème en ajoutant délibérément un répertoire non inscriptible à l'archive, mais cela n'a pas fonctionné, tar n'a pas mis à jour les autorisations sur le répertoire lorsqu'il a extrait l'archive:

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> 

J'ai également essayé de changer les autorisations sur test / a à 000, en l'ajoutant à l'archive, puis en ajoutant un autre test / a, mais celui-ci a bien fonctionné aussi:

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

Je voudrais donc vraiment voir l'archive d'origine qui a causé le problème et voir ce qui aurait pu être dans cette archive pour causer ce problème.

Si un nom de fichier et un répertoire partagent le même nom, tar a un problème d'extraction, mais il a un message d'erreur assez clair:

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.

(si le conflit s'est produit dans l'autre sens, c'est-à-dire qu'un fichier est arrivé en premier, puis un répertoire du même nom est venu plus tard, tar le supprime simplement et crée le répertoire:

Macbook> tar -xvf test.tar
x test/
x test/dir1
x test/
x test/dir1/
x test/dir1/a
Johnny
la source
1
J'ai précisé un peu plus clairement que le comportement dans son Gist (et sa réponse personnelle) ne semble pas être la réponse complète car les doublons de fichiers sont autorisés dans une archive tar. La réponse à "Je ne peux pas décompresser une archive tar avec un fichier dupliqué" ne devrait donc pas être "Supprimer le fichier en double" car tar est censé être capable de gérer ce cas.
Johnny
2
C'est vraiment un commentaire - il n'offre pas de solution, c'est seulement une discussion sur une solution existante. Johnny, pouvez-vous déplacer ceci vers un commentaire? Je reviendrai et supprimera cela plus tard, je voulais juste vous donner la possibilité de le déplacer en premier. Merci.
Ian C.
2
@Johnny, ces informations ne dispose d' informations super utiles, mais ce n'est pas une réponse à la question. C'est un commentaire sur une autre réponse. Pensez-y de cette façon: si la réponse de Geoff était supprimée, cette réponse serait-elle utile? Non, ce ne serait pas le cas. Vraiment, le contenu de cette réponse est "cette autre réponse de Geoff ne semble pas correcte". La question d'origine était "Qu'est-ce qui cause cette erreur?" La réponse la plus proche que vous pourriez obtenir était "Je ne sais pas ce qui en est la cause, mais ce n'est pas un fichier en double" - mais cela nécessiterait une modification, et ne répond toujours pas vraiment à la question d'origine.
DW
2
Je préfère que cela ne soit pas supprimé car l'image plus grande est que c'est un endroit pour apprendre, et les détails dans ce post sont superbes de l'OMI. +1 et aucune suppression nécessaire - Je pense que cela aidera les autres dans une situation similaire à comprendre s'ils n'ont pas le fichier corrompu de l'OP ou si l'interaction de corruption est différente, non?
bmike
2
@bmike et autres: j'ai ajouté une réponse qui devrait au moins expliquer ce qui se passe ici, mais pas nécessairement pourquoi.
Adam Liter
6

Il s'avère que l'utilitaire tar OS X était le bon! Il y avait en effet une erreur dans l'archive. Ce fil de discussion en parle plus en détail, mais le problème est qu'il y a un fichier en double dans l'archive . Les gars de SCIP réparent l'archive pendant que je tape ceci.

[edit]
Le scip-3.2.0.tgz nouvellement mis à jour est maintenant en train d'extraire très bien! Le hachage SHA-1 du nouveau tgz est 5b4e8283f4a5bf9e50f9a62d4320d6f5f50c8476.

[edit 2]
Ce n'est pas qu'il y ait une erreur dans l'archive. C'est simplement que bsdtar, qui est livré avec OS X, gère les fichiers en double différemment de celui gnutarqui est livré avec Linux. La réponse de @Adam Liter ici fournit une explication approfondie de ce qui se passe.

Geoff
la source
1
Intéressant. Alors peut-être que les autres utilitaires ignoraient l'erreur de fichier en double et continuaient sans se plaindre? Quoi qu'il en soit, heureux d'avoir trouvé la cause et la réponse.
TryTryAgain
1
Oui, je pense que c'est exactement ce que font les autres services publics. Je dirais que l'utilitaire tar OS X est le bon ici. Une archive mal formée doit toujours déclencher au moins un avertissement pour avertir l'utilisateur que quelque chose ne va pas. Merci de votre aide!
Geoff
Un fichier en double dans une archive tar n'en fait pas une archive mal formée, le format tar permet spécifiquement les dupes. Je suis curieux de savoir pourquoi votre mac tar a refusé de décompresser l'archive même si vous n'avez pas spécifié l' -koption, ce qui le mettrait en garde contre les fichiers préexistants. Malheureusement, ils ont déjà mis à jour le scip-3.2.0.tgzfichier pour supprimer la dupe, donc je ne peux pas tester cette archive.
Johnny
L' tarextrait réagit différemment en essayant d'extraire scip-3.2.0/applications/Coloring/Makefiledeux fois selon votre umask. Si le 1er créé ne vous laisse pas un accès en écriture, la 2ème tentative échoue.
dan
1
@DW J'ai ajouté une réponse qui explique pourquoi ce n'est pas une contradiction.
Adam Liter
1

Il existe un logiciel d'archivage alternatif, gratuit et léger que j'utilise pour Mac OSX. Cela s'appelle Keka et je l'utilise pour décompresser 7zip plus spécifiquement. De plus, il peut décompresser d'autres types comme .rar, .tar, .gz, etc.

ThisClark
la source