Чому вилучення цього ТГЗ призводить до помилки на моєму Mac, а не в Linux?


27

У мене виникає досить дивна проблема, і я не можу зрозуміти, що відбувається. У мене є файл tgz, scip-3.2.0.tgz , який видає помилку при спробі розпакувати її. Помилка трапляється лише в OS X (я 10.10.4). Я можу витягнути файл без помилок у вікні Linux із операційною системою CentOS 6.6. Помилка виникає як при використанні команди командного рядка, так tarі при використанні утиліти архіву. Я надіслав електронний лист розсилки SCIP, і у мене той самий хеш SHA-1, як і інший користувач ( e085a4a3591eddf945dcb365d97d2512c267e374), тому не було помилки при завантаженні. Вони не впевнені, що відбувається.

Ось помилка, яку я отримую, коли намагаюся розпакувати за допомогою утиліти архіву:

Помилка утиліти архіву

У випадку, якщо зображення колись порушиться, текст на зображенні говорить про це:

Неможливо розширити "scip-3.2.0.tgz" на "Настільний".
(Помилка 1 - Операція не дозволена.)

І коли я намагаюся розпакувати через командний рядок, це результат, який я отримую . Мене стосується останній рядок ( tar: Error exit delayed from previous errors.). Я не бачу, що це викликає. Архів, здається, витягується без проблем, але я не вірю йому, що ця помилка буде видалена.

Хтось знає, що це викликає?

[редагувати]
Подивившись трохи ближче на вихід, рядок 1108 містить помилку:

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

2
Чи працює це з іншим додатком, таким як unarchiver? wakaba.c3.cx/s/apps/unarchiver.html
TryTryAgain

Так! Цікаво, що вони роблять по-іншому. Частина проблеми полягає в тому, що у мене є сценарій bash, який автоматизує купу речей, і одна з речей, яку йому потрібно зробити, - це витягнути цей tgz, щоб він міг будувати те, що знаходиться всередині нього. Цікаво, чи є помилка в tarкоманді, яка постачається з OS X.
Джефф

1
Цілком можливо, є помилка. Я виявив, що вбудована утиліта архіву OS X є досить хитра. Чи немає способу повторного архівування потрібних файлів на блискавку чи щось таке? Крім того, якщо ви його розробляєте, чи виникає помилка, коли ви знаходитесь gunzip -c scip-3.2.0.tgz | tar xopf -з командного рядка, як би ви використовували її для свого сценарію?
TryTryAgain

Так, ця команда видає ту саму помилку. gunzipпрацює чудово, але коли я намагаюся витягнути нестиснений тарбол, тоді виникає помилка.
Джефф

Ага, виявляється, дійсно була помилка в тарболі! Я не божевільний. Я напишу більш детальну відповідь. Мабуть, утиліта tar для OS X була тут правильною!
Джефф

Відповіді:


32

Це має допомогти визначити, що відбувається у відповіді Джонні , а також відповісти на питання, чому це працює на Linux, але не на Mac.

Проблема полягає в тому, що використовується Mac OS X bsdtar, тоді як більшість систем Linux використовується gnutar.

Ви можете встановити gnutarна Mac з Homebrew, використовуючи brew install gnu-tar, який буде симлінк gnutarв /usr/local/binякість gtar.

Якщо ви встановите gnutar, ви можете відтворити проблему, скориставшись кроками у відповіді Джонні .

$ 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

Тож очевидно gnutarархівує речі по-іншому таким чином, що змушує bsdtarдушити дублікати. Факт, який gtar -ztvf test.tar.gzвказує на те, що друга інстанція test/aархівується як a, link to test/aє релевантним. Як в коментарях зазначає Джонні, gnutarдублікати зберігатимуться як жорсткі посилання, а не власне файл, який можна відключити --hard-dereference.

Тобто ви можете зробити наступне:

$ 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

Однак у цьому випадку ви, очевидно, не контролюєте створення тарболу, тому --hard-dereferenceце не є варіантом. На щастя, виходячи з відповіді ОП , схоже, що ця проблема була виправлена ​​вище за течією.

Тим не менш, якщо хтось інший зіткнеться з цією проблемою в майбутньому і потребує швидкого виправлення або має невідповідний обслуговуючий апарат, який працює вище за течією, існує рішення.

Визначивши, що таке дублікат, ви можете скористатися --fast-readпараметром bsdtar(зауважте, що цей параметр є лише частиною bsdtar, а не 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.

Отже, у прикладі іграшки, який я створив, слідуючи прикладу іграшки у відповіді Джонні , є копія файлу test/a. Таким чином, ви могли уникнути цієї проблеми, зробивши наступне:

# 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

Зауважте, крім того, що gnutarми із задоволенням розпаковуємо архів із дублікатами, створеними самим собою, навіть коли --hard-dereferenceпараметр не використовувався:

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

Отже, це відповідає на ваше запитання, чому помилка кидається на Mac, а не на Linux. (Більшість) дистрибутивів Linux, що постачаються gnutar, і оскільки, мабуть, тарбол був упакований gnutar, при розпакуванні помилок gnutarне буде, але при розпакуванні буде помилка bsdtar.


Для подальшого читання та довідок, можна поглянути на те, які відмінності між bsdtar та GNU tar? на Unix.SE.


Нічого собі, приємного сну, я не мав уявлення, що між гнутаром та bsd tar є якась значна різниця. На основі вашого gtar -tcvf, gnutar досить "розумний", щоб оптимізувати другий файл копії як посилання, а не дублювати його в архіві.
Джонні

Після перегляду документів виходить, що це побічний ефект від жорсткого поводження з gtar. Здається, що дублюючий файл насправді є жорстким посиланням на файл, тому він зберігає його як посилання замість фактичного файлу. Надання --hard-dereferenceопції gtar відключає цю поведінку.
Джонні

@Johnny Дійсно це зрозуміли двоє з доморощених (Місті Де Мео та Домінік Тіллер). Підтримувач деякого програмного забезпечення, який я використовую, випустив нову версію з дублікатом файлу в тарболі, що спричинило проблеми при спробі встановити нову версію з Homebrew (очевидно). У будь-якому випадку, дякую за перевірку документів! Я додам це до відповіді.
Адам Літер

Це чудово. Я відзначаю це відповіддю, оскільки це найточніше пояснення того, що відбувається. Спасибі!
Джефф

7

Наявність у архіві дублікату файлу не повинно зробити його недійсним або неможливим витягнути в OSX, як за замовчуванням, tar замінює дублікати.

Отже, я трохи зніяковіло поведінку в вашому Gist - OSX дьоготь дозволяє дублікати файлів в архіві (повернення до початкової мети , як т мавпа ара зубки утиліти, так що це дозволяє файли , які будуть додаватися в кінці стрічковий архів, і коли архів буде відновлено, найновіша версія файлу замінить старіші версії)

Лише тоді, коли присутній варіант "-k", tar повинен попереджати про наявні файли.

Тут я створив архів із дублюючим файлом, після чого без проблем вилучив його. Лише я не додав параметр -k, він попередив мене про повторюваний файл:

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

Проста проблема умаски теж не є винуватою, я спробував змінити свій umask на 0777, і я все ще можу витягнути архів:

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

Я думав, що міг би скопіювати проблему, навмисно додавши в архів непридатний каталог, але це не спрацювало, tar не оновив дозволи на каталог, коли він витягував архів:

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> 

Я також спробував змінити дозволи на тест / а на 000, додати їх до архіву, потім додати ще один тест / а, але і цей працював нормально:

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

Тому я дуже хотів би побачити оригінальний архів, який спричинив проблему, і побачити, що могло бути в цьому архіві, щоб викликати цю проблему.

Якщо ім’я файлу та каталогу мають одне ім’я, у tar виникла проблема з вилученням, але в ньому є досить чітке повідомлення про помилку:

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.

(якщо конфлікт трапився навпаки, тобто файл з’явився спочатку, то пізніше з'явився каталог з тим самим іменем. tar просто видаляє його і створює каталог:

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

1
Я зрозумів трохи зрозуміліше, що поведінка в його Gist (і його самовідповіді) не є повною відповіддю, оскільки копії файлів дозволені в архіві tar. Отже, відповідь на "Я не можу розпакувати архів дзеркалу з дублюваним файлом" не повинен бути "Видалити копію файлу", оскільки tar, як передбачається, зможе обробити цей випадок.
Джонні

2
Це дійсно коментар - він не пропонує рішення, це лише обговорення існуючого рішення. Джонні, чи можете ви, будь ласка, перенести це до коментаря? Я повернуся та видалю це пізніше, просто хотів дати вам шанс перенести його спочатку. Спасибі.
Ян Ч.

2
@Johnny, ця інформація дійсно має супер-цінну інформацію, але це не відповідь на питання. Це коментар до іншої відповіді. Подумайте про це так: якщо відповідь Джеффа була видалена, чи була б ця відповідь корисною? Ні, не буде. Дійсно, зміст цієї відповіді - "інша відповідь Джеффа не здається правильною". Первісне питання було "Що викликає цю помилку?" Найближчі до відповіді на те, що було "Я не знаю, що це викликає, але це не дублікат файлу" - але це вимагало б редагування, і все ще насправді не відповідає на початкове запитання.
DW

2
Я вважаю за краще це не видаляти, оскільки на більшій картині - це місце, де можна дізнатися, а деталі в цій публікації - чудові IMO. +1 і видалення не потрібно - я думаю, це допоможе іншим у подібній ситуації розібратися, якщо у них немає корумпованого файлу ОП або корупційна взаємодія відрізняється, ні?
bmike

2
@bmike та інші: я додав відповідь, яка повинна хоча б пояснити, що тут відбувається, хоча не обов’язково чому.
Адам Літер

6

Виявляється, утиліта OS X tar була правильною! В архіві справді була помилка. Цей потік електронної пошти обговорює його більш докладно, але проблема полягає в тому, що в архіві є дублікат файлу . Хлопці з SCIP виправляють архів, коли я це набираю.

[редагувати]
Нещодавно оновлений scip-3.2.0.tgz тепер витягується просто чудово! Хеш SHA-1 нового tgz є 5b4e8283f4a5bf9e50f9a62d4320d6f5f50c8476.

[редагувати 2]
Справа не в тому, що в архіві є помилка. Це просто те bsdtar, що постачається з OS X, обробляє дублікати файлів інакше, ніж те gnutar, що постачається з Linux. Відповідь @Adam - літровий в тут дає докладне пояснення того , що відбувається.


1
Цікаво. То, може, інші утиліти ігнорували помилку дублікату файлу та рухалися далі, не скаржившись? У будь-якому разі, радий, що ти знайшов причину та відповідь.
TryTryAgain

1
Так, я думаю, що саме цим займаються інші комунальні служби. Я б заперечував, що утиліта OS X tar є правильною тут. Несправний архів повинен завжди створювати принаймні попередження, щоб попереджати користувача про те, що щось не працює. Спасибі за вашу допомогу!
Джефф

Дублікат файлу в архіві дьогтю не робить його неправильним архівом, формат смоли спеціально дозволяє виконувати документи. Мені цікаво, чому ваш mac tar відмовився розпаковувати архів, навіть якщо ви не вказали конкретний -kпараметр, який би сповіщав про попередні файли. На жаль, вони вже оновили scip-3.2.0.tgzфайл, щоб видалити дуп, тому я не можу перевірити цей архів.
Джонні

tarЕкстракт по- різному реагує на спробу витягти scip-3.2.0/applications/Coloring/Makefileдва рази в залежності від вашого umask. Якщо перша створена не залишає вам доступ для запису, друга спроба не працює.
дан

1
@DW Я додав відповідь, яка пояснює, чому це не суперечність.
Адам Літер

1

Є альтернативне, безкоштовне, легке архівне програмне забезпечення, яке я використовую для Mac OSX. Це називається Keka, і я використовую його для розпакування 7zip конкретніше. Більше того, він може розпакувати інші типи, такі як .rar, .tar, .gz тощо. Він також працював для специфічного файлу tar для ОП, але я спробував це після того, як @Geoff згадав, що команда працювала над ремонтом файлу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.