3

Я видел другие вопросы, связанные с этой ошибкой (например, Извлечение файла tar.gz возвращает «Это не похоже на архив tar.»), Но я не уверен, как применить их к моей проблеме:

Сначала скачайте файл:

$ wget --no-check-certificate https://wxpython.org/Phoenix/tools/doxygen-1.8.8-linux.bz2
--2017-04-06 15:06:11--  https://wxpython.org/Phoenix/tools/doxygen-1.8.8-linux.bz2
Resolving wxpython.org (wxpython.org)... 85.234.150.54
Connecting to wxpython.org (wxpython.org)|85.234.150.54|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3961996 (3.8M) [application/x-bzip2]
Saving to: ‘doxygen-1.8.8-linux.bz2’

100%[==============================================================================>] 3,961,996    734KB/s   in 5.0s   

2017-04-06 15:06:16 (778 KB/s) - ‘doxygen-1.8.8-linux.bz2’ saved [3961996/3961996]

Затем проверьте тип файла:

$ file doxygen-1.8.8-linux.bz2 
doxygen-1.8.8-linux.bz2: bzip2 compressed data, block size = 900k

Ну, это "сжатые данные bzip2", давайте распакуем его?

$ tar xjvf doxygen-1.8.8-linux.bz2
tar: This does not look like a tar archive
tar: Skipping to next header
tar: Archive contains ‘\351\357\377I\211\304H\211’ where numeric mode_t value expected
tar: Archive contains ‘A\270\001\0\0\0H\211ǹ\001’ where numeric time_t value expected
tar: Archive contains ‘\307\350\216v)\0I\307’ where numeric uid_t value expected
tar: Archive contains ‘\004$P\254|\0\2770’ where numeric gid_t value expected
@\2678\350\330\351\357\377\2778
tar: @\2678\350\330\351\357\377\2778: Unknown file type '', extracted as normal file
tar: @�8������8: implausibly old time stamp 1970-01-01 00:59:59
tar: Skipping to next header
tar: Exiting with failure status due to previous errors

И я получаю пустой файл распакованным:

$ ls -la @�8������8 
-rwxrwxr-x 1 user user 0 Jan  1  1970 @?8??????8

Странно, если я использую file-roller (Archive Manager) и распаковываю из GUI, я получаю распакованный файл:

$ ls -la ~/Desktop/doxygen-1.8.8-linux 
-rw-rw-r-- 1 user user 12283548 Apr  6 15:13 /home/user/Desktop/doxygen-1.8.8-linux
$ file ~/Desktop/doxygen-1.8.8-linux 
/home/user/Desktop/doxygen-1.8.8-linux: ELF 64-bit LSB  executable, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0eccee11d38322d5df3a1723651c2f18303e1188, not stripped

Итак, что здесь происходит - почему я не могу распаковать это из командной строки, и как я могу распаковать это с помощью командной строки?


РЕДАКТИРОВАТЬ: на самом деле я могу распаковать его с:

$ bzip2 -d doxygen-1.8.8-linux.bz2 
$ file doxygen-1.8.8-linux 
doxygen-1.8.8-linux: ELF 64-bit LSB  executable, x86-64, version 1 (GNU/Linux), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0eccee11d38322d5df3a1723651c2f18303e1188, not stripped

... так что остается только один вопрос - почему я не мог использовать tar для этого, как всегда делал иначе?

2 ответа2

22

tar просто копирует файлы в один большой файл .tar без сжатия. bzip2 , gzip , xz - это файловые компрессоры для отдельных файлов, т.е. tar файлы Расширение: .tar.gz , .tar.xz , .tar.bz2 или .tbz(2), .txz , .tgz и т.д.

tar может обрабатывать только файлы .tar со сжатием или без сжатия с помощью bzip2, xz, gzip. но не архивы .bz2 , .xz .

Bzip-файлы без tar могут быть извлечены с помощью bzip2 -d file.bz2 .

1

Причина, по которой ваш файл "не похож на архив tar", заключается в том, что это не архив tar, а всего лишь один исполняемый файл, сжатый bzip2. Вы можете сказать это по выходным данным команды file , а также по тому факту, что ваш файл не имеет расширения имени файла .tar.bz2 , а только .bz2 (хотя, конечно, технически можно переименовать любой файл, чтобы иметь любой расширение).

Думайте о tar и bzip2 как об отдельных слоях с разными целями: tar объединяет кучу разных файлов в один большой файл, а bzip2 сжимает файл (часто вывод tar), содержащий повторяющиеся данные, кодируя повторяющиеся части в более компактный путь.

Tar часто используется вместе с bzip2 (или gzip или другими подобными программами сжатия файлов) по двум основным причинам:

  1. Архивы tar являются отличными кандидатами на сжатие bzip2, так как они часто содержат много повторяющихся данных, и так как часто желательно сжать их как можно меньше, чтобы сэкономить место.

    Кроме того, как следует из названия, архивы tar обычно используются для архивирования данных, к которым не ожидается частый доступ или их частое изменение. Таким образом, тот факт, что сжатие и распаковка bzip2 делают доступ к контенту и его изменение медленнее, не является для них особой проблемой.

  2. По своей конструкции bzip2 (и gzip и т.д.) Не могут сжимать более одного файла одновременно. Если вы хотите создать один сжатый архив bzip2, содержащий несколько файлов, вам нужно сначала скопировать файлы вместе.

    Этот дизайн является частью философии Unix, заключающейся в создании инструментов, каждый из которых выполняет свою работу и делает это хорошо. Tar объединяет файлы Bzip2 сжимает файлы. Одним из преимуществ этой модульной конструкции по сравнению с другими популярными инструментами сжатия, такими как zip , которые предназначены для обеих одновременно, является то, что каждая часть легко заменяется, не затрагивая другую. Например, bzip2 - это (в некоторых отношениях) улучшенная замена вставки для gzip, которая, в свою очередь, является заменой для старой программы сжатия . Все они, а также любые другие, даже лучшие программы сжатия файлов (например, xz), существующие сейчас или в будущем, могут использоваться для сжатия одних и тех же архивов tar.

Поскольку tar и xz / bzip2 / gzip / compress часто используются вместе, многие распространенные реализации tar (в том числе tar GNU, обычно используемый в Linux) предоставляют некоторые дополнительные удобные функции для работы со сжатыми архивами. В частности, им может быть предложено (через переключатели командной строки) автоматически сжимать свои упакованные выходные данные с помощью одной из этих программ сжатия, и они могут обнаруживать архивы, которые были таким образом сжаты, и автоматически распаковывать их перед распаковкой. Однако эти функции существуют только для удобства пользователя: те же самые результаты могут быть достигнуты просто путем передачи ввода / вывода tar через bzip2 или какой-либо другой файловый компрессор.


Тем не менее, иногда вы хотите использовать либо деготь или только bzip2, без других. Примечательно, что если у вас есть только один большой файл, который вы хотите сжать, тогда вам действительно не нужны дополнительные затраты на его предварительное сжатие - более эффективно просто применить bzip2 непосредственно к исходному файлу. Это то, что у вас есть: один большой сжатый bzip2 файл.

Если вы попытаетесь передать этот файл в tar, он сначала правильно обнаружит, что он сжат bzip2, и попытается распаковать его перед дальнейшей обработкой. Но поскольку вы явно вызываете tar, он ожидает фактического получения (возможно, сжатого) архива tar, а когда он не находит того, что ожидает после распаковки ввода, он выдает сообщение об ошибке, которое вы видели.

Вместо этого, как уже отмечал Майкл Д. в комментариях, вы можете распаковать этот файл напрямую, используя bzip2, с помощью:

bzip2 -d doxygen-1.8.8-linux.bz2

или (эквивалентно):

bunzip2 doxygen-1.8.8-linux.bz2

По умолчанию, когда b(un)zip2 вызывается так, распакованный файл будет иметь то же имя, что и оригинал, за исключением расширения .bz2 . После успешной распаковки исходный сжатый файл будет автоматически удален. (Если вы не хотите этого, передайте параметр -k или --keep в b(un)zip2.) Конечно, вы можете также повторно сжать несжатый файл с помощью:

bzip2 doxygen-1.8.8-linux

В качестве альтернативы, вы можете просто передать данные в b(un)zip2 через stdin и получить соответствующие (не) сжатые данные через stdout, например:

bunzip2 < doxygen-1.8.8-linux.bz2 > doxygen-1.8.8-linux-or-whatever

Это делает то же самое, что и предыдущая команда bunzip2 выше, за исключением того, что она не будет (и не может) автоматически удалять входной файл, и что вы можете дать выходному файлу любое имя, какое захотите.

Более полезно, вы также можете передать вход и / или выход b(un)zip2 в / из другой программы. Например, вместо того, чтобы сначала загрузить сжатый файл на диск с помощью wget, а затем распаковать его, вы можете просто направить вывод wget непосредственно в bunzip2:

wget --output-document=- \
  https://wxpython.org/Phoenix/tools/doxygen-1.8.8-linux.bz2 \
  | bunzip2 > doxygen-1.8.8-linux

Параметр --output-document=- (который может быть сокращен до -O -) указывает wget записать загруженные данные в стандартный вывод вместо сохранения их на диск. Затем последняя строка направляет вывод wget в bunzip2 и направляет вывод bunzip2 в файл doxygen-1.8.8-linux . Обратная косая черта просто помечает места, где я разбил команду на несколько строк для удобства чтения; оболочка будет игнорировать их и разрывы строк, которые следуют за ними.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .