Как открыть файл tar.gz, созданный с помощью tar, переданного через gzip

Вопрос или проблема

Я хотел создать файл tar gz с максимальным уровнем сжатия и следовал решению из https://superuser.com/a/546509/461740:

tar cv /path/to/directory | gzip -9 > file.tar.gz

Но теперь я не могу распаковать файл, у меня следующая ошибка:

tar: This does not look like a tar archive
tar: Skipping to next header
tar: Archive contains ‘23241_at',16’ where numeric off_t value expected 

Я погуглил эту ошибку, в большинстве случаев она вызвана “двойным” сжатием gzip, я попробовал предложенные решения для этой проблемы, но, похоже, это не относится к моей проблеме.

Есть идеи, как это исправить?

Примечание: когда я вызвал команду file для нераспакованного файла (который, как предполагается, является файлом tar), я получил результат: data.

Редактировать: результат head -c512 file.tar | hexdump -C:

00000000  73 71 6c 5f 64 75 6d 70  2f 0a 73 71 6c 5f 64 75  |sql_dump/.sql_du|
00000010  6d 70 2f 62 67 65 65 46  6f 72 65 69 67 6e 4b 65  |mp/bgeeForeignKe|
00000020  79 2e 73 71 6c 0a 73 71  6c 5f 64 75 6d 70 2f 00  |y.sql.sql_dump/.|
00000030  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000080  00 00 00 00 00 00 00 00  00 00 30 30 30 30 37 35  |..........000075|
00000090  35 00 30 30 30 37 36 34  33 00 30 30 31 31 33 30  |5.0007643.001130|
000000a0  30 00 30 30 30 30 30 30  30 30 30 30 30 00 31 32  |0.00000000000.12|
000000b0  35 33 35 31 36 30 34 34  34 00 30 31 32 37 30 33  |535160444.012703|
000000c0  00 20 35 00 00 00 00 00  00 00 00 00 00 00 00 00  |. 5.............|
000000d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000120  00 00 00 00 00 00 00 75  73 74 61 72 20 20 00 66  |.......ustar  .f|
00000130  62 61 73 74 69 61 6e 00  00 00 00 00 00 00 00 00  |bastian.........|
00000140  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 75  |...............u|
00000150  6e 69 6c 64 65 65 00 00  00 00 00 00 00 00 00 00  |nildee..........|
00000160  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000200

Следуя команде @kasperd для попытки восстановить мой файл, tail -c+39 file.tar > repaired.tar, шестнадцатеричный дамп первых 512 байт:

00000000  73 71 6c 5f 64 75 6d 70  2f 00 00 00 00 00 00 00  |sql_dump/.......|
00000010  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000060  00 00 00 00 30 30 30 30  37 35 35 00 30 30 30 37  |....0000755.0007|
00000070  36 34 33 00 30 30 31 31  33 30 30 00 30 30 30 30  |643.0011300.0000|
00000080  30 30 30 30 30 30 30 00  31 32 35 33 35 31 36 30  |0000000.12535160|
00000090  34 34 34 00 30 31 32 37  30 33 00 20 35 00 00 00  |444.012703. 5...|
000000a0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000100  00 75 73 74 61 72 20 20  00 66 62 61 73 74 69 61  |.ustar  .fbastia|
00000110  6e 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |n...............|
00000120  00 00 00 00 00 00 00 00  00 75 6e 69 6c 64 65 65  |.........unildee|
00000130  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000200

Результат tar -tvf на “исправленном” tar:

drwxr-xr-x username  0 2015-06-08 02:26 sql_dump/
-rw-r--r-- username 19123 2015-06-08 02:25 sql_dump/bgeeForeignKey.sql
tar: Skipping to next header
tar: Archive contains `688_x_at\',1' where numeric off_t value expected
tar: Archive contains `y\',\'not ' where numeric mode_t value expected
tar: Archive contains `725,\'ENSG' where numeric time_t value expected
tar: Archive contains `excluded' where numeric uid_t value expected
tar: Archive contains `\'),(\'208' where numeric gid_t value expected
tar: Archive contains `excluded' where numeric uid_t value expected
tar: Archive contains `\'),(\'208' where numeric gid_t value expected
?rwsrwsrwt 4294967295/4294967295 18446744073709551615 1970-01-01 00:59 ty','not excluded'),('208686_s_at',13725,'ENSG00000204256',7.73,'present',15097863,NULL,'high qualit unknown file type `\''
tar: Skipping to next header
tar: Archive contains `ent\'),(31801' where numeric off_t value expected
tar: Archive contains `no data\'' where numeric mode_t value expected
tar: Archive contains `347,\'ENSG' where numeric time_t value expected
tar: Archive contains `,\'no dat' where numeric uid_t value expected
tar: Archive contains `a\',\'desc' where numeric gid_t value expected
tar: Archive contains `,\'no dat' where numeric uid_t value expected
tar: Archive contains `a\',\'desc' where numeric gid_t value expected
?rwsrwsrwt 4294967295/4294967295 18446744073709551615 1970-01-01 00:59 ,'descent'),(31801346,'ENSG00000104375','UBERON:0007625','HsapDv:0000095','no data','poor quality',' unknown file type `\''
tar: Skipping to next header
tar: Exiting with failure status due to previous errors

Вывод dd if=repaired.tar skip=39 count=2 | hexdump -C

2+0 records in
2+0 records out
1024 bytes (1.0 kB) copied00000000  64 64 20 66 6f 72 65 69  67 6e 20 6b 65 79 20 28  |dd foreign key (|
00000010  64 69 66 66 65 72 65 6e  74 69 61 6c 45 78 70 72  |differentialExpr|
00000020  65 73 73 69 6f 6e 49 64  29 20 72 65 66 65 72 65  |essionId) refere|
00000030  6e 63 65 73 20 64 69 66  66 65 72 65 6e 74 69 61  |nces differentia|
00000040  6c 45 78 70 72 65 73 73  69 6f 6e 28 64 69 66 66  |lExpression(diff|
, 6.9324e-05 s, 14.8 MB/s
00000050  65 72 65 6e 74 69 61 6c  45 78 70 72 65 73 73 69  |erentialExpressi|
00000060  6f 6e 49 64 29 20 6f 6e  20 64 65 6c 65 74 65 20  |onId) on delete |
00000070  73 65 74 20 6e 75 6c 6c  3b 0a 2f 2a 21 34 30 30  |set null;./*!400|
00000080  30 30 20 41 4c 54 45 52  20 54 41 42 4c 45 20 60  |00 ALTER TABLE `|
00000090  64 65 61 52 4e 41 53 65  71 53 75 6d 6d 61 72 79  |deaRNASeqSummary|
000000a0  60 20 45 4e 41 42 4c 45  20 4b 45 59 53 20 2a 2f  |` ENABLE KEYS */|
000000b0  3b 0a 0a 00 00 00 00 00  00 00 00 00 00 00 00 00  |;...............|
000000c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000200  73 71 6c 5f 64 75 6d 70  2f 52 45 41 44 4d 45 2e  |sql_dump/README.|
00000210  74 78 74 0a 73 71 6c 5f  64 75 6d 70 2f 62 67 65  |txt.sql_dump/bge|
00000220  65 49 6e 64 65 78 2e 73  71 6c 0a 73 71 6c 5f 64  |eIndex.sql.sql_d|
00000230  75 6d 70 2f 64 75 6d 70  5f 62 67 65 65 5f 76 31  |ump/dump_bgee_v1|
00000240  33 5f 31 2e 73 71 6c 0a  73 71 6c 5f 64 75 6d 70  |3_1.sql.sql_dump|
00000250  2f 52 45 41 44 4d 45 2e  74 78 74 00 00 00 00 00  |/README.txt.....|
00000260  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000002a0  00 00 00 00 00 00 00 00  00 00 00 00 30 30 30 30  |............0000|
000002b0  36 34 34 00 30 30 30 37  36 34 33 00 30 30 31 31  |644.0007643.0011|
000002c0  33 30 30 00 30 30 30 30  30 30 30 32 30 36 34 00  |300.00000002064.|
000002d0  31 32 35 33 35 31 36 30  31 37 34 00 30 31 34 34  |12535160174.0144|
000002e0  30 33 00 20 30 00 00 00  00 00 00 00 00 00 00 00  |03. 0...........|
000002f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000340  00 00 00 00 00 00 00 00  00 75 73 74 61 72 20 20  |.........ustar  |
00000350  00 66 62 61 73 74 69 61  6e 00 00 00 00 00 00 00  |.fbastian.......|
00000360  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000370  00 75 6e 69 6c 64 65 65  00 00 00 00 00 00 00 00  |.unildee........|
00000380  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400

Если всё в порядке, должно быть достаточно

tar -zxvf file.tar.gz

опция z нужна для сжатия gzip.
На tar (GNU tar) 1.27.1 это работает тоже без

tar -xvf Myfile.tar.gz

Если нет специальной причины делать так, как вы использовали, вы можете создать файл tar gz напрямую с помощью

tar -zcvf Myfile.tar.gz  /path/to/directory

или используя другую программу сжатия, например

tar -jcvf Myfile.tar.bz  /path/to/directory

Чтобы проверить, с каким типом файла вы имеете дело, используйте команду file

file *.tar.*

Myfile.tar.gz: gzip compressed data, from Unix, last modified:...
Myfile.tar.bz: bzip2 compressed data, block size = 900k
tar -xvfz file.tar.gz
  • -x извлечение
  • -z распаковка
  • -v подробный вывод

Обновление

Попробуйте также это:

gunzip < file.tar.gz | tar xvf -

С вашей командой создания архива всё в порядке. Вы можете просмотреть содержимое и проверить контрольную сумму архива с помощью этой команды:

tar -tzf file.tar.gz

Из вашего вопроса следует, что файл, который у вас сейчас, на самом деле не является файлом .tar.gz. Что-то непреднамеренное должно было случиться с файлом, и варианты, которые я могу предположить, следующие:

  1. Вы как-то неправильно ввели команду для создания архива в первую очередь.
  2. Или команда tar, или gzip в вашем PATH были не настоящими версиями, а чем-то другим, создающим неправильный вывод.
  3. У вас была переменная окружения, заменяющая библиотеку, используемую программами, на неисправную версию.
  4. Ошибка аппаратного обеспечения вызвала искажение данных.
  5. Некоторая программа была использована для изменения файла между временем его создания и временем попытки извлечения.

Чтобы выяснить, что действительно произошло с этим файлом и как его можно восстановить, нам нужно внимательно изучить фактическое содержимое файла.

В предоставленном вами шестнадцатеричном дампе я заметил, что многие поля находятся не на правильной выравнивании в заголовке. Сравнивая с хорошим tar файлом, я вижу, что в вашем файле поля расположены на 38 байт дальше внутри файла.

Кроме того, я заметил, что первая директория внутри вашего архива имеет очень длинное имя, в котором даже есть новая строка на 38-м байте.

Поэтому я прихожу к выводу, что содержимое вашего файла не просто tar архив. Это одна строка текста, за которой следует tar архив. Ошибочная строка гласит

sql_dump/.sql_dump/bgeeForeignKey.sql

Я не знаю, как вы успели получить эту строку, хранящуюся внутри вашего .tar.gz файла. Но если мы пропустим её, первая директория будет иметь гораздо более разумное имя sql_dump/. Если это единственное искажение, вы сможете восстановить данные с помощью этой одной команды:

tail -c+39 file.tar > repaired.tar

Вы забыли минус для перенаправления вывода tar в pipe:

$ tar cf - /path/to/directory | gzip -9 > file.tar.gz

.

Ответ или решение

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

Теория

Формат tar.gz представляет собой комбинацию двух форматов: tar и gzip. Команда tar используется для упаковки нескольких файлов и/или директорий в один архив, а gzip — для сжатия этого архива. Традиционно архив создается следующей командой:

tar -cf - /path/to/directory | gzip -9 > file.tar.gz

Здесь флаг -c означает создание архива, флаг -f позволяет задавать имя файла через стандартный ввод (-), и gzip -9 указывает на использование максимального уровня сжатия.

Пример

В вашем случае отсутствует дефис - после флага -f. Это важная деталь: без этого дефиса tar не указывает на вывод в стандартный поток, что может привести к записи неправильного содержимого в файл file.tar.gz.

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

Применение

Для исправления проблемы попробуйте следующее:

  1. Убедитесь, что команда создания архива была выполнена корректно:
tar -cf - /path/to/directory | gzip -9 > file.tar.gz
  1. Если файл уже создан и вы не можете его прочитать, проверьте его целостность. Возможно, файл поврежден или данные были записаны неправильно. Воспользуйтесь следующей командой для предварительной оценки проблемы:
file file.tar.gz

Она покажет, какой тип данных сохранен в файле. Правильно сжатый tar-архив должен быть определен как gzip compressed data.

  1. Если анализ с помощью file выдает что-то, отличное от ожидаемого, попробуйте вручную исследовать содержимое с помощью hexdump или аналогичного инструмента для понимания структуры ошибки, как это уже сделано в предоставленной части текста.

  2. Если данные внутри файла выглядят как текст, случайно добавленный в бинарный поток, попробуйте исправить файл, удалив первые байты, например:

tail -c+39 file.tar.gz > corrected.tar.gz
  1. После этого можно разархивировать исправленный файл командой:
gunzip < corrected.tar.gz | tar xvf -
  1. Проверьте, были ли данные успешно извлечены, и не содержат ли они временных меток 1970-01-01, что может свидетельствовать о дополнительной порче данных.

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

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...