Dlaczego wyodrębnianie tego tgz powoduje błąd na moim Macu, ale nie na Linuksie?

27

Mam dość dziwny problem i nie mogę zrozumieć, co się dzieje. Mam plik tgz, scip-3.2.0.tgz , który zgłasza błąd podczas próby rozpakowania. Błąd występuje tylko w systemie OS X (mam 10.10.4). Mogę wyodrębnić plik bez błędu na komputerze z systemem Linux z systemem CentOS 6.6. Błąd występuje, gdy używa się zarówno wiersza tarpolecenia, jak i narzędzia do archiwizacji. Wysłałem e-mailem listę mailingową SCIP i mam taki sam skrót SHA-1 jak inny użytkownik ( e085a4a3591eddf945dcb365d97d2512c267e374), więc nie wystąpił błąd pobierania. Nie są pewni, co się dzieje.

Oto błąd, który pojawia się podczas próby rozpakowania za pomocą narzędzia do archiwizacji:

błąd narzędzia archiwizacji

W przypadku uszkodzenia obrazu tekst na obrazku mówi:

Nie można rozwinąć „scip-3.2.0.tgz” do „Desktop”.
(Błąd 1 - Operacja niedozwolona.)

A kiedy próbuję rozpakować za pomocą wiersza polecenia, otrzymuję dane wyjściowe . To ostatnia linia ( tar: Error exit delayed from previous errors.), która mnie dotyczy. Nie rozumiem, co to powoduje. Archiwum wydaje się rozpakowywać bez problemu, ale nie ufam temu z powodu zgłoszenia błędu.

Czy ktoś wie, co to powoduje?

[edytuj]
Przyglądając się nieco bliżej wyjścia, wiersz 1108 zawiera błąd:

x scip-3.2.0/applications/Coloring/Makefile: Can't create 'scip-3.2.0/applications/Coloring/Makefile'
Geoff
źródło
2
Czy to działa z inną aplikacją, taką jak unarchiver? wakaba.c3.cx/s/apps/unarchiver.html
TryTryAgain
Tak! Zastanawiam się, co robią inaczej. Częściowym problemem jest to, że mam skrypt bash, który automatyzuje wiele rzeczy, a jedną z rzeczy, które musi zrobić, jest wyodrębnienie tego tgz, aby mógł zbudować to, co jest w nim. Zastanawiam się, czy w tarpoleceniu dostarczonym z OS X jest błąd.
Geoff,
1
Całkiem możliwe, że jest błąd. Zauważyłem, że wbudowane narzędzie do archiwizacji OS X jest dość kiepskie. Czy nie ma możliwości ponownego zarchiwizowania potrzebnych plików do formatu zip lub czegoś takiego? Ponadto, jeśli piszesz skrypt, czy błąd pojawia się również gunzip -c scip-3.2.0.tgz | tar xopf -w wierszu poleceń, tak jak w przypadku skryptu?
TryTryAgain
Tak, to polecenie powoduje ten sam błąd. gunzipdziała dobrze, ale kiedy próbuję wyodrębnić nieskompresowane archiwum, wtedy pojawia się błąd.
Geoff,
Ach, okazuje się, że rzeczywiście był błąd w tarballu! Ja nie jestem szalony. Napiszę bardziej szczegółową odpowiedź. Najwyraźniej narzędzie tar w OS X było tutaj poprawne!
Geoff,

Odpowiedzi:

32

To powinno pomóc zidentyfikować, co się dzieje w odpowiedzi Johnny'ego , a także odpowiedzieć na pytanie, dlaczego działa to w Linuksie, ale nie na Macu.

Problem polega na tym, że używa Mac OS X bsdtar, podczas gdy większość systemów Linux gnutar.

Możesz zainstalować gnutarna komputerze Mac z Homebrew, używając brew install gnu-tar, który będzie dowiązaniem symbolicznym gnutardo /usr/local/binas gtar.

Jeśli zainstalujesz gnutar, możesz odtworzyć problem, wykonując czynności opisane w odpowiedzi Johnny'ego .

$ 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

Więc oczywiście gnutararchiwizuje rzeczy inaczej, w sposób, który powoduje bsdtarzadławienie duplikatów. gtar -ztvf test.tar.gzIstotny jest fakt, który wskazuje, że druga instancja test/ajest zarchiwizowana jako a link to test/a. Jak zauważa Johnny w komentarzach, gnutarbędą przechowywać duplikaty jako twarde linki zamiast rzeczywistego pliku, który można wyłączyć --hard-dereference.

Oznacza to, że możesz wykonać następujące czynności:

$ 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

Jednak w tym przypadku oczywiście nie kontrolujesz tworzenia tarballa, więc --hard-dereferencenie ma takiej opcji. Na szczęście, na podstawie odpowiedzi PO , wydaje się, że problem ten został rozwiązany przez upstream.

Niemniej jednak, jeśli ktokolwiek inny napotka ten problem w przyszłości i potrzebuje szybkiej naprawy lub nie odpowiada na wcześniejszego opiekuna, istnieje obejście tego problemu.

Po określeniu, co to jest zduplikowany plik, możesz skorzystać z --fast-readopcji bsdtar(pamiętaj, że ta opcja jest tylko częścią bsdtar, a nie 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.

Tak więc w przykładzie zabawki, który utworzyłem zgodnie z przykładem zabawki w odpowiedzi Johnny'ego , zduplikowany plik to test/a. W ten sposób można uniknąć tego problemu, wykonując następujące czynności:

# 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

Należy ponadto pamiętać, że z gnutarprzyjemnością rozpakowuje archiwum z duplikatami, które zostało utworzone przez siebie, nawet jeśli --hard-dereferencenie użyto opcji:

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

Odpowiada to na pytanie, dlaczego błąd jest generowany na Macu, ale nie na Linuksie. (Większość) dystrybucje Linuksa są dostarczane z gnutar, a ponieważ tarball był prawdopodobnie spakowany gnutar, nie będzie błędu podczas rozpakowywania gnutar, ale wystąpi błąd podczas rozpakowywania bsdtar.


W celu dalszej lektury i odniesienia warto przyjrzeć się różnicom między bsdtar a GNU tar? na Unix.SE.

Adam Liter
źródło
Wow, niezły snuthing, nie miałem pojęcia, że ​​istnieje jakakolwiek znacząca różnica między gnutarem a smołą bsd. W oparciu o twoje gtar -tcvf, gnutar jest wystarczająco „inteligentny”, aby zoptymalizować drugi plik kopii jako łącze zamiast kopiowania go w archiwum.
Johnny
Po przeszukaniu dokumentów wygląda na to, że jest to efekt uboczny obsługi twardego linku w gtar. Wydaje się, że zduplikowany plik jest w rzeczywistości twardym linkiem do pliku, więc zapisuje go jako łącze zamiast rzeczywistego pliku. Podanie --hard-dereferenceopcji gtar wyłącza to zachowanie.
Johnny
@Johnny Tak naprawdę to dwóch opiekunów Homebrew to wymyśliło (Misty De Meo i Dominyk Tiller). Opiekun używanego przeze mnie oprogramowania wydał nową wersję ze zduplikowanym plikiem w archiwum, co spowodowało problemy przy próbie zainstalowania nowej wersji z Homebrew (oczywiście). W każdym razie dzięki za sprawdzenie dokumentów! Dodam to do odpowiedzi.
Adam Liter
To jest doskonałe. Zaznaczam tę odpowiedź, ponieważ jest to najdokładniejsze wyjaśnienie tego, co się dzieje. Dzięki!
Geoff,
7

Istnienie duplikatu pliku w archiwum nie powinno powodować, że będzie on nieprawidłowy lub nie będzie można go wyodrębnić w OSX, ponieważ domyślnie tar zastępuje duplikaty.

Tak, jestem trochę zdezorientowany przez zachowanie w Twoim Gist - OSX tar pozwala na duplikatów plików w archiwum (powrotem do swojego pierwotnego celu jako t małpy ar szczypiorek użyteczności, co pozwala pliki mają być dołączone do końca archiwum taśmowe, a po przywróceniu archiwum najnowsza wersja pliku zastąpi starsze wersje

Tylko wtedy, gdy obecna jest opcja „-k”, tar powinien ostrzegać o istniejących plikach.

Tutaj utworzyłem archiwum ze zduplikowanym plikiem, a następnie wyodrębniłem je bez problemu. Dopiero po dodaniu opcji -k ostrzegło mnie przed zduplikowanym plikiem:

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

Prosty problem z umaskiem również nie wydaje się być winowajcą. Próbowałem zmienić swój umask na 0777 i nadal mogę rozpakować archiwum:

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

Pomyślałem, że mogę zduplikować problem, celowo dodając do archiwum niezapisywalny katalog, ale to nie zadziałało, tar nie zaktualizował uprawnień do katalogu podczas rozpakowywania archiwum:

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> 

Próbowałem także zmienić uprawnienia do testu / a na 000, dołączając je do archiwum, a następnie dołączając kolejny test / a, ale ten również działał dobrze:

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

Naprawdę chciałbym zobaczyć oryginalne archiwum, które spowodowało problem i zobaczyć, co mogło być w tym archiwum, aby spowodować ten problem.

Jeśli nazwa pliku i katalog mają tę samą nazwę, tar ma problem z wyodrębnieniem, ale ma dość wyraźny komunikat o błędzie:

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.

(jeśli konflikt zdarzył się na odwrót, tzn. plik pojawił się jako pierwszy, potem katalog o tej samej nazwie pojawił się później, tar po prostu go usuwa i tworzy katalog:

Macbook> tar -xvf test.tar
x test/
x test/dir1
x test/
x test/dir1/
x test/dir1/a
Jasio
źródło
1
Wyjaśniłem trochę bardziej, że zachowanie w jego Gist (i jego własnej odpowiedzi) nie wydaje się być pełną odpowiedzią, ponieważ duplikaty plików są dozwolone w archiwum tar. Tak więc odpowiedź na „Nie mogę rozpakować archiwum tar ze zduplikowanym plikiem” nie powinna brzmieć „Usuń duplikat pliku”, ponieważ tar powinien być w stanie obsłużyć tę sprawę.
Johnny
2
To naprawdę komentarz - nie oferuje rozwiązania, jest tylko dyskusją na temat istniejącego rozwiązania. Johnny, możesz przenieść to do komentarza? Wrócę i usunę to później, chciałem tylko dać ci szansę, aby to przenieść. Dzięki.
Ian C.
2
@Johnny, ta informacja zawiera bardzo cenne informacje, ale nie jest to odpowiedź na pytanie. To komentarz do innej odpowiedzi. Pomyśl o tym w ten sposób: jeśli odpowiedź Geoffa zostanie usunięta, czy ta odpowiedź byłaby przydatna? Nie zrobiłby tego. Naprawdę, treść tej odpowiedzi brzmi „ta inna odpowiedź Geoffa wydaje się nieprawidłowa”. Pierwotne pytanie brzmiało: „Co powoduje ten błąd?” Najbliżej odpowiedzi można było odpowiedzieć: „Nie wiem, co go powoduje, ale nie jest to duplikat pliku” - ale wymagałoby to edycji i nadal nie odpowiada na oryginalne pytanie.
DW
2
Wolę tego nie usuwać, ponieważ większy obraz to miejsce do nauki, a szczegóły w tym poście są znakomite IMO. +1 i nie trzeba usuwać - myślę, że pomoże to innym osobom w podobnej sytuacji dowiedzieć się, czy nie mają uszkodzonego pliku PO, czy interakcja uszkodzenia jest inna, prawda?
bmike
2
@bike i inni: Dodałem odpowiedź, która powinna przynajmniej wyjaśnić, co się tutaj dzieje, choć niekoniecznie dlaczego.
Adam Liter
6

Okazuje się, że narzędzie tar OS X było prawidłowe! W archiwum rzeczywiście wystąpił błąd. W tym wątku e-mailowym omówiono go bardziej szczegółowo, ale problem polega na tym, że w archiwum znajduje się duplikat pliku . Chłopaki SCIP naprawiają archiwum, pisząc to.

[edytuj]
Nowa aktualizacja scip-3.2.0.tgz jest teraz w porządku. Skrót SHA-1 nowego tgz to 5b4e8283f4a5bf9e50f9a62d4320d6f5f50c8476.

[edycja 2]
To nie jest tak, że w archiwum jest błąd. Po prostu ten bsdtar, który jest dostarczany z OS X, obsługuje duplikaty plików inaczej niż gnutar, który jest dostarczany z Linuksem. @Adam Liter odpowiedź tutaj zapewnia dokładne wyjaśnienie tego, co się dzieje.

Geoff
źródło
1
Ciekawy. Więc może inne narzędzia ignorowały błąd duplikatu pliku i działały bez narzekań? W każdym razie cieszę się, że znalazłeś przyczynę i odpowiedź.
TryTryAgain
1
Tak, myślę, że dokładnie to robią inne narzędzia. Twierdziłbym, że narzędzie tar OS X jest tutaj właściwe. Zniekształcone archiwum powinno zawsze generować przynajmniej ostrzeżenie, aby ostrzec użytkownika, że ​​coś jest wyłączone. Dzięki za pomoc!
Geoff,
Duplikat pliku w archiwum tar nie czyni go zniekształconym archiwum, format tar specjalnie zezwala na kopie. Jestem ciekawy, dlaczego twój mac tar odmówił rozpakowania archiwum, mimo że nie -kokreśliłeś opcji, która ostrzegałaby przed istniejącymi plikami. Niestety zaktualizowali już scip-3.2.0.tgzplik, aby usunąć duplikat, więc nie mogę przetestować tego archiwum.
Johnny
tarEkstrakt różnie reagują na próby wyodrębnić scip-3.2.0/applications/Coloring/Makefiledwa razy w zależności od Państwa umask. Jeśli 1. utworzony plik nie pozostawia dostępu do zapisu, 2. próba się nie powiedzie.
dan
1
@DW Dodałem odpowiedź, która wyjaśnia, dlaczego nie jest to sprzeczność.
Adam Liter
1

Istnieje alternatywne, bezpłatne, lekkie oprogramowanie do archiwizacji, którego używam na Mac OSX. Nazywa się Keka i używam go do rozpakowywania 7zip w szczególności. Co więcej, może rozpakować inne typy, takie jak .rar, .tar, .gz itp. Działa to również dla konkretnego pliku tar OP, ale spróbowałem go po tym, jak @Geoff wspomniał, że zespół pracuje nad naprawą pliku.

ThisClark
źródło