Cela devrait aider à identifier ce qui se passe dans la réponse de Johnny, ainsi que répondre à la question de pourquoi cela fonctionne sur Linux mais pas sur Mac.
Le problème réside dans le fait que Mac OS X utilise bsdtar
, tandis que la plupart des systèmes Linux utilisent gnutar
.
Vous pouvez installer gnutar
sur un Mac avec Homebrew, en utilisant brew install gnu-tar
, qui créera un lien symbolique de gnutar
dans /usr/local/bin
en tant que 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
==> Téléchargement de https://homebrew.bintray.com/bottles/gnu-tar-1.28.yosemite.bottle.2.tar.gz
######################################################################## 100.0%
==> Écoulement de gnu-tar-1.28.yosemite.bottle.2.tar.gz
==> Remarques
gnu-tar a été installé sous le nom "gtar".
Si vous avez vraiment besoin de l'utiliser en tant que "tar", vous pouvez ajouter un répertoire "gnubin"
à votre PATH à partir de votre bashrc comme suit :
PATH="/usr/local/opt/gnu-tar/libexec/gnubin:$PATH"
==> Résumé
/usr/local/Cellar/gnu-tar/1.28: 13 fichiers, 1.6M
$ mkdir test
$ touch test/a test/b
$ gtar -zcvf test.tar.gz test test/a # créer l'archive avec 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 lien vers test/a
$ rm -r test
$ tar -xvf test.tar.gz # essayer de déballer l'archive avec bsdtar
x test/
x test/a
x test/b
x test/a: Impossible de créer 'test/a'
tar: L'erreur d'arrêt est retardée par rapport aux erreurs précédentes.
$ echo $?
1
Il est évident que gnutar
archive les choses différemment d'une manière qui fait que bsdtar
s'étouffe sur les doublons. Le fait que gtar -ztvf test.tar.gz
indique que la deuxième instance de test/a
est archivée sous la forme d'un lien vers test/a
est pertinent. Comme Johnny le souligne dans les commentaires, gnutar
stocke les doublons sous forme de liens physiques au lieu du fichier réel, ce qui peut être désactivé avec --hard-dereference
.
C'est-à-dire, vous pourriez faire ce qui suit :
$ 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 # notez que ce n'est plus un lien
$ rm -r test
$ tar -xvf test.tar.gz # déballer avec 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 du fichier tar, donc --hard-dereference
n'est pas une option. Heureusement, d'après la réponse de l'OP, il semble que ce problème ait été résolu par les développeurs.
Néanmoins, si quelqu'un d'autre rencontre ce problème à l'avenir et a besoin d'une solution rapide ou si le mainteneur en amont ne répond pas, il existe une solution de contournement.
Une fois que vous avez identifié le fichier en double, vous pouvez utiliser l'option --fast-read
de bsdtar
(notez que cette option fait uniquement partie de bsdtar
, pas de gnutar
) :
-q (--fast-read)
(mode x et t uniquement) Extraire ou lister uniquement la première entrée d'archive qui correspond à chaque motif ou opérande de nom de fichier. Sortez dès que chaque motif ou opérande de nom spécifié a été associé. Par défaut, l'archive est toujours lue jusqu'à la fin, car il peut y avoir plusieurs entrées avec le même nom et, par convention, les entrées ultérieures écrasent les entrées antérieures. Cette option est fournie en tant qu'optimisation des performances.
Ainsi, dans l'exemple simplifié que j'ai créé suivant l'exemple simplifié dans la réponse de Johnny, le fichier en double est test/a
. Ainsi, vous pourriez éviter ce problème en faisant ce qui suit :
# cette série de commandes fait suite à la première série de commandes
# autrement dit, ce qui suit suppose un fichier tar qui n'a pas été créé avec
# l'option --hard-dereference, bien que cela fonctionnera tout aussi bien
# avec l'option activée
$ tar -xvqf test.tar.gz test/a # décompresser la première instance de test/a
x test/a
$ tar -xvf test.tar.gz --exclude test/a # décompresser tout sauf test/a
x test/
x test/b
$ echo $?
0
$ ls test/
a b
Remarquez également que gnutar
peut parfaitement décompresser une archive avec des doublons qui a été créée par lui-même, même lorsque l'option --hard-dereference
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
Ainsi, cela répond à votre question de pourquoi une erreur est générée sur Mac mais pas sur Linux. La plupart des distributions Linux embarquent gnutar
, et puisque le fichier tar a probablement été empaqueté avec gnutar
, il n'y aura pas d'erreur lors du déballage avec gnutar
, mais il y en aura une lors du déballage avec bsdtar
.
Pour plus de lecture et de référence, on peut consulter Quelles sont les différences entre bsdtar et GNU tar? sur Unix.SE.
2 votes
Est-ce que cela fonctionne avec une autre application comme Unarchiver ? wakaba.c3.cx/s/apps/unarchiver.html
0 votes
Oui, cela fait! 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 pour qu'il puisse construire ce qui se trouve à l'intérieur. Je me demande s'il y a un bug dans la commande
tar
fournie avec OS X.1 votes
Peut-être qu'il y a un bug. J'ai trouvé l'utilitaire d'archivage intégré d'OS X assez nul. N'y a-t-il aucun moyen de réarchiver les fichiers nécessaires dans un zip ou quelque chose comme ça? De plus, si vous mettez en place un script, l'erreur se produit-elle également lorsque vous
gunzip -c scip-3.2.0.tgz | tar xopf -
à partir de la ligne de commande, comme vous l'utiliseriez pour votre script?0 votes
Oui, cette commande renvoie la même erreur.
gunzip
fonctionne très bien, mais lorsque j'essaie d'extraire le tarball non compressé, c'est là que l'erreur se produit.0 votes
Ah, il s'avère qu'il y avait en effet une erreur dans le tarball! Je ne suis pas fou. Je vais rédiger une réponse plus détaillée. Apparemment, l'utilitaire tar dans OS X était le bon ici!
0 votes
Quel est votre
umask
sur les 2 systèmes sur lesquels vous avez exécuté cetar
?0 votes
Sur mon Mac,
umask
est 0022. Sur la machine Linux, c'est 0002.