¿Por qué extraer este tgz arroja un error en mi Mac pero no en Linux?

27

Estoy experimentando un problema bastante extraño, y no puedo entender qué está pasando. Tengo un archivo tgz, scip-3.2.0.tgz , que arroja un error cuando intento descomprimirlo. El error solo ocurre en OS X (estoy en 10.10.4). Puedo extraer el archivo sin error en una caja de Linux que ejecuta CentOS 6.6. El error ocurre cuando se usa el comando de línea de tarcomando y cuando se usa la utilidad de archivo. Envié un correo electrónico a la lista de correo SCIP, y tengo el mismo hash SHA-1 que otro usuario ( e085a4a3591eddf945dcb365d97d2512c267e374), por lo que no hubo un error de descarga. No están seguros de lo que está pasando.

Aquí está el error que obtengo cuando intento descomprimir usando la utilidad de archivo:

error de utilidad de archivo

En caso de que la imagen alguna vez se rompa, el texto en la imagen dice esto:

No se puede expandir "scip-3.2.0.tgz" en "Escritorio".
(Error 1 - Operación no permitida).

Y cuando trato de descomprimir a través de la línea de comando, este es el resultado que obtengo . Es la última línea ( tar: Error exit delayed from previous errors.) lo que me preocupa. No veo lo que lo está causando. El archivo parece extraerse sin problema, pero no confío en que se arroje ese error.

¿Alguien sabe qué está causando esto?

[edit]
Mirando un poco más de cerca la salida, la línea 1108 contiene el error:

x scip-3.2.0/applications/Coloring/Makefile: Can't create 'scip-3.2.0/applications/Coloring/Makefile'
Geoff
fuente
2
¿Funciona con otra aplicación como el Unarchiver? wakaba.c3.cx/s/apps/unarchiver.html
Try TryAgain
Si, lo hace! Me pregunto qué están haciendo de manera diferente. Parte del problema es que tengo un script bash que automatiza un montón de cosas, y una de las cosas que debe hacer es extraer este tgz para que pueda construir lo que está dentro de él. Me pregunto si hay un error en el tarcomando que viene con OS X.
Geoff
1
Muy posiblemente, hay un error. He encontrado que la utilidad de archivo OS X integrada es bastante mala. ¿No hay forma de volver a archivar los archivos necesarios en un archivo zip o algo así? Además, si está creando una secuencia de comandos, ¿el error también ocurre cuando gunzip -c scip-3.2.0.tgz | tar xopf -sale de la línea de comandos, ya que lo usaría para su secuencia de comandos?
Try TryAgain
Sí, ese comando arroja el mismo error. gunzipfunciona bien, pero cuando trato de extraer el tarball sin comprimir, es cuando se produce el error.
Geoff
¡Ah, resulta que sí hubo un error en el tarball! No estoy loco. Escribiré una respuesta más detallada. ¡Aparentemente, la utilidad tar en OS X fue la correcta aquí!
Geoff

Respuestas:

32

Esto debería ayudar a identificar lo que está sucediendo en la respuesta de Johnny , así como a responder la pregunta de por qué esto funciona en Linux pero no en Mac.

El problema radica en el hecho de que Mac OS X usa bsdtar, mientras que la mayoría de los sistemas Linux usan gnutar.

Se puede instalar gnutaren un Mac con Homebrew, utilizando brew install gnu-tar, lo que enlazar simbólicamente gnutaren /usr/local/bintan gtar.

Si lo instala gnutar, puede reproducir el problema siguiendo los pasos de la respuesta 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

Por lo tanto, obviamente gnutararchiva las cosas de manera diferente, lo que hace bsdtarque se ahogue con los duplicados. El hecho de que gtar -ztvf test.tar.gzla segunda instancia de test/ase archiva como a link to test/aes relevante. Como señala Johnny en los comentarios, gnutaralmacenará duplicados como enlaces duros en lugar del archivo real, que se puede desactivar con --hard-dereference.

Es decir, puede hacer lo siguiente:

$ 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

Sin embargo, en este caso, obviamente no controlas la creación del tarball, por --hard-dereferencelo que no es una opción. Afortunadamente, según la respuesta del OP , parece que este problema se ha solucionado en sentido ascendente.

No obstante, si alguien más se encuentra con este problema en el futuro y necesita una solución rápida o tiene un mantenedor ascendente que no responde, hay una solución alternativa.

Una vez que identifique cuál es el archivo duplicado, puede usar la --fast-readopción de bsdtar(tenga en cuenta que esta opción es solo parte de bsdtar, no 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.

Entonces, en el ejemplo de juguete que he creado siguiendo el ejemplo de juguete en la respuesta de Johnny , el archivo duplicado es test/a. Por lo tanto, puede evitar este problema haciendo lo siguiente:

# 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

Tenga en cuenta, además, que gnutarestá perfectamente feliz de descomprimir un archivo con duplicados que fue creado por sí mismo, incluso cuando la --hard-dereferenceopción no se utilizó:

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

Entonces esto responde a su pregunta de por qué se produce un error en Mac pero no en Linux. (La mayoría) de las distribuciones de Linux se envían con gnutar, y dado que el tarball fue presumiblemente empaquetado gnutar, no habrá ningún error al desempacar gnutar, pero habrá un error al desempacar con bsdtar.


Para una lectura y referencia adicional, uno puede mirar ¿Cuáles son las diferencias entre bsdtar y GNU tar? en Unix.SE.

Adam Litro
fuente
Wow, agradable investigación, no tenía idea de que hubiera alguna diferencia significativa entre gnutar y bsd tar. Según su gtar -tcvf, gnutar es lo suficientemente "inteligente" como para optimizar el segundo archivo de copia como un enlace en lugar de duplicarlo en el archivo.
Johnny
Después de buscar en los documentos, parece que este es un efecto secundario del manejo de enlaces duros de gtar. Parece pensar que el archivo duplicado es en realidad un enlace duro al archivo, por lo que lo almacena como un enlace en lugar del archivo real. Darle a gtar la --hard-dereferenceopción deshabilita este comportamiento.
Johnny
@Johnny Fueron realmente dos de los mantenedores de Homebrew quienes descubrieron esto (Misty De Meo y Dominyk Tiller). Un mantenedor de algún software que uso lanzó una nueva versión con un archivo duplicado en el tarball, lo que causó problemas al intentar instalar la nueva versión con Homebrew (obviamente). De todos modos, ¡gracias por revisar los documentos! Agregaré eso a la respuesta.
Adam Liter
Esto es excelente. Estoy marcando esto como la respuesta, ya que es la explicación más completa de lo que está sucediendo. ¡Gracias!
Geoff
7

La existencia de un archivo duplicado en el archivo no debe invalidarlo o no se puede extraer en OSX, ya que, de forma predeterminada, tar sobrescribe los duplicados.

Por lo tanto, estoy un poco confundido por el comportamiento en su Gist - OSX tar permite que los archivos duplicados en un archivo (una vuelta a su propósito original como t mono ar cebolleta utilidad, por lo que permite que los archivos que se añaden al final de el archivo de cinta, y cuando se restaura el archivo, la versión más reciente del archivo sobrescribirá las versiones anteriores)

Solo cuando la opción "-k" está presente, tar debe advertir sobre los archivos preexistentes.

Aquí creé un archivo con un archivo duplicado y luego lo extraje sin problemas. No fue hasta que agregué la opción -k que me advirtió sobre el archivo duplicado:

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 problema de umask tampoco parece ser el culpable, intenté cambiar mi umask a 0777 y aún puedo extraer el archivo:

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

Pensé que podría duplicar el problema agregando deliberadamente un directorio no grabable al archivo, pero eso no funcionó, tar no actualizó los permisos en el directorio cuando extrajo el archivo:

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> 

También intenté cambiar los permisos en la prueba / a a 000, agregarlo al archivo y luego agregar otra prueba / a, pero esa también funcionó bien:

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

Así que realmente me gustaría ver el archivo original que causó el problema y ver qué podría haber estado en ese archivo para causar este problema.

Si un nombre de archivo y un directorio comparten el mismo nombre, tar tiene un problema para extraerlo, pero tiene un mensaje de error bastante claro:

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 el conflicto ocurrió al revés, es decir, primero vino un archivo, luego vino un directorio con el mismo nombre, tar simplemente lo elimina y crea el directorio:

Macbook> tar -xvf test.tar
x test/
x test/dir1
x test/
x test/dir1/
x test/dir1/a
Johnny
fuente
1
Dejé un poco más claro que el comportamiento en su Gist (y su respuesta propia) no parece ser la respuesta completa porque los duplicados de archivos están permitidos en un archivo tar. Por lo tanto, la respuesta a "No puedo descomprimir un archivo tar con un archivo duplicado" no debería ser "Eliminar el archivo duplicado", ya que se supone que tar puede manejar ese caso.
Johnny
2
Esto es realmente un comentario: no ofrece una solución, es solo una discusión sobre una solución existente. Johnny, ¿puedes mover esto a un comentario? Volveré y borraré esto más tarde, solo quería darte la oportunidad de moverlo primero. Gracias.
Ian C.
2
@Johnny, esta información tiene información súper valiosa, pero no es una respuesta a la pregunta. Es un comentario sobre otra respuesta. Piénselo de esta manera: si la respuesta de Geoff fue eliminada, ¿sería útil esta respuesta? No, no lo haría. Realmente, el contenido de esta respuesta es "esa otra respuesta de Geoff no parece correcta". La pregunta original era "¿Qué está causando este error?" Lo más cercano que pudo llegar a responder fue "No sé qué lo está causando, pero no es un archivo duplicado", pero eso requeriría una edición, y aún así no responde la pregunta original.
DW
2
Prefiero que esto no se elimine, ya que la imagen más grande es un lugar para aprender, y los detalles en esta publicación son IMO excelentes. Se necesita +1 y no se necesita eliminar: creo que ayudará a otros en una situación similar a resolver las cosas si no tienen el archivo corrupto del OP o si la interacción de corrupción es diferente, ¿no?
bmike
2
@bmike y otros: he agregado una respuesta que al menos debería explicar lo que está sucediendo aquí, aunque no necesariamente por qué.
Adam Liter
6

¡Resulta que la utilidad tar de OS X era la correcta! De hecho, hubo un error en el archivo. Este hilo de correo electrónico lo analiza con más detalle, pero el problema es que hay un archivo duplicado en el archivo . Los chicos de SCIP están arreglando el archivo mientras escribo esto.

[editar] ¡
El scip-3.2.0.tgz recientemente actualizado se está extrayendo perfectamente! El hash SHA-1 del nuevo tgz es 5b4e8283f4a5bf9e50f9a62d4320d6f5f50c8476.

[editar 2]
No es que haya un error en el archivo. Es simplemente eso bsdtar, que se envía con OS X, maneja los archivos duplicados de manera diferente que gnutar, que se envía con Linux. La respuesta de @Adam Liter aquí proporciona una explicación detallada de lo que está sucediendo.

Geoff
fuente
1
Interesante. Entonces, ¿tal vez las otras utilidades ignoraban el error del archivo duplicado y continuaban sin quejarse? De todos modos, me alegro de haber encontrado la causa y la respuesta.
Try TryAgain
1
Sí, creo que eso es exactamente lo que están haciendo las otras utilidades. Yo diría que la utilidad de tar OS X es la correcta aquí. Un archivo con formato incorrecto siempre debe generar al menos una advertencia para alertar al usuario de que algo está apagado. ¡Gracias por tu ayuda!
Geoff
Un archivo duplicado en un archivo tar no lo convierte en un archivo con formato incorrecto, el formato tar permite específicamente duplicados. Tengo curiosidad por saber por qué su tar de Mac se negó a desempaquetar el archivo aunque no especificó la -kopción, lo que lo advertiría sobre archivos preexistentes. Desafortunadamente, ya han actualizado elscip-3.2.0.tgz archivo para eliminar el engaño, por lo que no puedo probar ese archivo.
Johnny
los tar extracto reacciona de manera diferente al tratar de extraer scip-3.2.0/applications/Coloring/Makefiledos veces dependiendo de su umask. Si el primero creado no te deja un acceso de escritura, el segundo intento falla.
dan
1
@DW He agregado una respuesta que explica por qué esto no es una contradicción.
Adam Liter
1

Hay un software de archivo alternativo, gratuito y liviano que uso para Mac OSX. Se llama Keka y lo uso para descomprimir 7zip más específicamente. Además, puede descomprimir otros tipos como .rar, .tar, .gz, etc. Funcionó también para el archivo tar específico del OP, pero lo intenté después de que @Geoff mencionara que el equipo estaba trabajando en la reparación del archivo.

ThisClark
fuente