Perché l'estrazione di questo tgz genera un errore sul mio Mac ma non su Linux?


27

Sto riscontrando un problema piuttosto strano e non riesco a capire cosa stia succedendo. Ho un file tgz, scip-3.2.0.tgz , che genera un errore quando tento di decomprimerlo. L'errore si verifica solo su OS X (sono il 10.10.4). Posso estrarre il file senza errori su un box Linux con CentOS 6.6. L'errore si verifica sia quando si utilizza il comando da riga di tarcomando sia quando si utilizza l'utilità di archiviazione. Ho inviato un'email alla mailing list SCIP e ho lo stesso hash SHA-1 di un altro utente ( e085a4a3591eddf945dcb365d97d2512c267e374), quindi non si è verificato un errore di download. Non sono sicuri di cosa stia succedendo.

Ecco l'errore che ottengo quando provo a decomprimere utilizzando l'utilità di archiviazione:

errore dell'utilità di archiviazione

Nel caso in cui l'immagine venga mai rotta, il testo nell'immagine dice questo:

Impossibile espandere "scip-3.2.0.tgz" in "Desktop".
(Errore 1 - Operazione non consentita.)

E quando provo a decomprimere tramite la riga di comando, questo è l'output che ottengo . È l'ultima riga ( tar: Error exit delayed from previous errors.) che mi riguarda. Non vedo cosa lo stia causando. L'archivio sembra estrarre senza problemi, ma non mi fido di questo errore.

Qualcuno sa cosa sta causando questo?

[modifica]
Osservando un po 'più da vicino l'output, la riga 1108 contiene l'errore:

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

2
Funziona con un'altra app come l'archiviatore? wakaba.c3.cx/s/apps/unarchiver.html
Try TryAgain

Sì, lo fa! Mi chiedo cosa stiano facendo diversamente. Parte del problema è che ho uno script bash che automatizza un sacco di cose, e una delle cose che deve fare è estrarre questo tgz in modo che possa costruire ciò che c'è dentro. Mi chiedo se c'è un bug nel tarcomando fornito con OS X.
Geoff,

1
Molto probabilmente, c'è un bug. Ho trovato l'utilità di archiviazione integrata in OS X piuttosto scadente. Non c'è modo di ri-archiviare i file necessari in una zip o qualcosa del genere? Inoltre, se lo stai copiando, l'errore si verifica anche quando sei gunzip -c scip-3.2.0.tgz | tar xopf -dalla riga di comando, come lo useresti per il tuo script?
Prova TryAgain

Sì, quel comando genera lo stesso errore. gunzipfunziona bene, ma quando provo ad estrarre il tarball non compresso, è allora che viene generato l'errore.
Geoff,

Ah, si è scoperto che c'era davvero un errore nel tarball! Non sono pazzo. Scriverò una risposta più dettagliata. Apparentemente l'utilità tar in OS X era quella corretta qui!
Geoff,

Risposte:


32

Questo dovrebbe aiutare a identificare cosa sta succedendo nella risposta di Johnny , così come rispondere alla domanda sul perché questo funziona su Linux ma non su Mac.

Il problema sta nel fatto che Mac OS X lo utilizza bsdtar, mentre la maggior parte dei sistemi Linux lo utilizza gnutar.

Puoi installarlo gnutarsu un Mac con Homebrew, usando brew install gnu-tar, che si collegherà simbolicamente gnutara /usr/local/bincome gtar.

Se lo installi gnutar, puoi riprodurre il problema usando i passaggi nella risposta di 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

Quindi ovviamente gnutararchivia le cose in modo diverso in un modo che fa bsdtarsoffocare i duplicati. È gtar -ztvf test.tar.gzrilevante il fatto che indichi che la seconda istanza di test/aè archiviata come a link to test/a. Come sottolinea Johnny nei commenti, i gnutarduplicati verranno archiviati come collegamenti reali anziché come file effettivo, che può essere disabilitato con --hard-dereference.

Cioè, potresti fare quanto segue:

$ 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

Tuttavia, in questo caso, ovviamente non controlli la creazione del tarball, quindi --hard-dereferencenon è un'opzione. Fortunatamente, in base alla risposta del PO , sembra che questo problema sia stato risolto a monte.

Tuttavia, se qualcun altro si imbatte in questo problema in futuro e ha bisogno di una soluzione rapida o ha un manutentore a monte che non risponde, c'è una soluzione alternativa.

Una volta identificato il file duplicato, è possibile utilizzare l' --fast-readopzione di bsdtar(notare che questa opzione è solo una parte di bsdtar, non 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.

Quindi, nell'esempio giocattolo che ho creato seguendo l'esempio giocattolo nella risposta di Johnny , il file duplicato è test/a. Pertanto, è possibile evitare questo problema procedendo come segue:

# 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

Si noti, inoltre, che gnutarè perfettamente felice di decomprimere un archivio con i duplicati che è stato creato da solo, anche quando l' --hard-dereferenceopzione non è stata utilizzata:

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

Quindi questo risponde alla tua domanda sul perché viene generato un errore su Mac ma non su Linux. (La maggior parte) distribuzioni Linux vengono fornite con gnutar, e poiché il tarball è stato presumibilmente impacchettato con gnutar, non ci saranno errori durante il disimballaggio con gnutar, ma ci sarà un errore durante il disimballaggio con bsdtar.


Per ulteriori letture e riferimenti, si potrebbe voler esaminare Quali sono le differenze tra bsdtar e GNU tar? su Unix.SE.


Caspita, carino, non avevo idea che ci fosse una differenza significativa tra gnutar e bsd tar. Basato sul tuo gtar -tcvf, gnutar è abbastanza "intelligente" per ottimizzare il secondo file di copia come link invece di duplicarlo nell'archivio.
Johnny,

Dopo aver analizzato i documenti, sembra che questo sia un effetto collaterale della gestione dei collegamenti fisici di gtar. Sembra pensare che il file duplicato sia in realtà un collegamento reale al file, quindi lo memorizza come collegamento anziché come file effettivo. Dare a gtar l' --hard-dereferenceopzione disabilita questo comportamento.
Johnny,

@Johnny Sono stati davvero due dei manutentori di Homebrew a capirlo (Misty De Meo e Dominyk Tiller). Un manutentore di alcuni software che utilizzo ha rilasciato una nuova versione con un file duplicato nel tarball, il che ha causato problemi durante il tentativo di installare la nuova versione con Homebrew (ovviamente). Comunque, grazie per aver controllato i documenti! Lo aggiungerò alla risposta.
Adam Liter,

Questo è eccellente Sto contrassegnando questa come risposta poiché è la spiegazione più completa di ciò che sta succedendo. Grazie!
Geoff,

7

L'esistenza di un file duplicato nell'archivio non dovrebbe renderlo non valido o impossibile da estrarre su OSX, poiché per impostazione predefinita tar sovrascrive i duplicati.

Quindi, io sono un po 'confuso dal comportamento nel vostro Gist - OSX tar permette per i file duplicati in un archivio (un ritorno alla sua originaria funzione di t scimmia ar erba cipollina utilità, in modo da permette ai file di essere aggiunto alla fine del l'archivio nastro e quando l'archivio viene ripristinato, la versione più recente del file sovrascriverà le versioni precedenti

È solo quando è presente l'opzione "-k" che tar dovrebbe avvisare dei file preesistenti.

Qui ho creato un archivio con un file duplicato, quindi l'ho estratto senza problemi. Solo quando ho aggiunto l'opzione -k mi ha avvertito del file duplicato:

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

Neanche un semplice problema di umask sembra essere il colpevole, ho provato a cambiare la mia umask a 0777 e posso ancora estrarre l'archivio:

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

Ho pensato di poter duplicare il problema aggiungendo deliberatamente una directory non scrivibile all'archivio, ma che non ha funzionato, tar non ha aggiornato le autorizzazioni sulla directory quando ha estratto l'archivio:

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> 

Ho anche provato a modificare le autorizzazioni su test / a su 000, aggiungendolo all'archivio, quindi aggiungendo un altro test / a, ma anche quello ha funzionato bene:

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

Quindi mi piacerebbe davvero vedere l'archivio originale che ha causato il problema e vedere cosa avrebbe potuto essere in quell'archivio per causare questo problema.

Se un nome file e una directory condividono lo stesso nome, tar ha un problema con l'estrazione, ma ha un messaggio di errore abbastanza chiaro:

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.

(se il conflitto si è verificato al contrario, ovvero un file è arrivato per primo, poi è arrivata una directory con lo stesso nome, tar lo rimuove e crea la directory:

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

1
Ho reso un po 'più chiaro che il comportamento nel suo Gist (e nella sua auto-risposta) non sembra essere la risposta completa perché i duplicati di file sono consentiti in un archivio tar. Quindi la risposta a "Non riesco a decomprimere un archivio tar con un file duplicato" non dovrebbe essere "Rimuovi il file duplicato" poiché Tar dovrebbe essere in grado di gestire quel caso.
Johnny,

2
Questo è davvero un commento: non offre una soluzione, è solo una discussione su una soluzione esistente. Johnny, puoi per favore spostarlo in un commento? Tornerò e lo cancellerò più tardi, volevo solo darti la possibilità di spostarlo prima. Grazie.
Ian C.

2
@Johnny, questa informazione ha informazioni super preziose, ma non è una risposta alla domanda. È un commento su un'altra risposta. Pensala in questo modo: se la risposta di Geoff fosse cancellata, questa risposta sarebbe utile? No, non lo farebbe. Davvero, il contenuto di questa risposta è "che l'altra risposta di Geoff non sembra corretta". La domanda originale era "Cosa sta causando questo errore?" Il più vicino a cui potresti rispondere è "Non so cosa lo stia causando, ma non è un file duplicato", ma ciò richiederebbe una modifica e non risponde ancora alla domanda originale.
DW,

2
Preferirei che questo non venisse cancellato dal momento che l'immagine più grande è che questo è un posto dove imparare, ei dettagli in questo post sono IMO superbi. +1 e nessuna cancellazione necessaria - Penso che aiuterà gli altri in una situazione simile a capire se non hanno il file corrotto dell'OP o se l'interazione con la corruzione è diversa, no?
bmike

2
@bmike e altri: ho aggiunto una risposta che dovrebbe almeno spiegare cosa sta succedendo qui, anche se non necessariamente perché.
Adam Liter,

6

Si scopre che l'utilità tar OS X era quella corretta! Si è effettivamente verificato un errore nell'archivio. Questo thread di posta elettronica ne discute in modo più dettagliato, ma il problema è che nell'archivio è presente un file duplicato . I ragazzi di SCIP stanno riparando l'archivio mentre scrivo questo.

[modifica]
Lo scip-3.2.0.tgz appena aggiornato sta estraendo bene! L'hash SHA-1 del nuovo tgz è 5b4e8283f4a5bf9e50f9a62d4320d6f5f50c8476.

[modifica 2]
Non è che ci sia un errore nell'archivio. È semplicemente quello bsdtar, che viene fornito con OS X, gestisce i file duplicati in modo diverso rispetto a gnutar, che viene fornito con Linux. La risposta di @Adam Liter qui fornisce una spiegazione approfondita di ciò che sta accadendo.


1
Interessante. Quindi forse le altre utility ignoravano l'errore del file duplicato e proseguivano senza lamentarsi? Comunque, felice di aver trovato la causa e la risposta.
Prova TryAgain

1
Sì, penso che sia esattamente quello che stanno facendo le altre utility. Direi che l'utilità tar OS X è quella giusta qui. Un archivio non valido deve sempre generare almeno un avviso per avvisare l'utente che qualcosa è spento. Grazie per l'aiuto!
Geoff,

Un file duplicato in un archivio tar non lo rende un archivio non valido, il formato tar consente specificamente i duplicati. Sono curioso di -ksapere perché il tuo mac tar ha rifiutato di decomprimere l'archivio anche se non hai specificato l' opzione, il che lo metterebbe in guardia sui file preesistenti. Sfortunatamente, hanno già aggiornato il scip-3.2.0.tgzfile per rimuovere il duplicato, quindi non posso provare quell'archivio.
Johnny,

L' tarestratto reagisce in modo diverso cercando di estrarre scip-3.2.0/applications/Coloring/Makefiledue volte a seconda del tuo umask. Se il primo creato non ti lascia un accesso in scrittura, il secondo tentativo fallisce.
dan

1
@DW Ho aggiunto una risposta che spiega perché questa non è una contraddizione.
Adam Liter,

1

Esiste un software di archiviazione alternativo, gratuito e leggero che utilizzo per Mac OSX. Si chiama Keka e lo uso per decomprimere 7zip in modo più specifico. Inoltre, può decomprimere altri tipi come .rar, .tar, .gz ecc. Ha funzionato anche per il file tar specifico dell'OP, ma l'ho provato dopo che @Geoff ha detto che il team stava lavorando per riparare il file.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.