Вопрос или проблема
Я хотел создать файл 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
. Что-то непреднамеренное должно было случиться с файлом, и варианты, которые я могу предположить, следующие:
- Вы как-то неправильно ввели команду для создания архива в первую очередь.
- Или команда
tar
, илиgzip
в вашемPATH
были не настоящими версиями, а чем-то другим, создающим неправильный вывод. - У вас была переменная окружения, заменяющая библиотеку, используемую программами, на неисправную версию.
- Ошибка аппаратного обеспечения вызвала искажение данных.
- Некоторая программа была использована для изменения файла между временем его создания и временем попытки извлечения.
Чтобы выяснить, что действительно произошло с этим файлом и как его можно восстановить, нам нужно внимательно изучить фактическое содержимое файла.
В предоставленном вами шестнадцатеричном дампе я заметил, что многие поля находятся не на правильной выравнивании в заголовке. Сравнивая с хорошим 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
.
Если после исправления команды проблема сохраняется, может существовать вероятность повреждения файла или иной проблемы, связанной с его первоначальным созданием.
Применение
Для исправления проблемы попробуйте следующее:
- Убедитесь, что команда создания архива была выполнена корректно:
tar -cf - /path/to/directory | gzip -9 > file.tar.gz
- Если файл уже создан и вы не можете его прочитать, проверьте его целостность. Возможно, файл поврежден или данные были записаны неправильно. Воспользуйтесь следующей командой для предварительной оценки проблемы:
file file.tar.gz
Она покажет, какой тип данных сохранен в файле. Правильно сжатый tar-архив должен быть определен как gzip compressed data
.
-
Если анализ с помощью
file
выдает что-то, отличное от ожидаемого, попробуйте вручную исследовать содержимое с помощьюhexdump
или аналогичного инструмента для понимания структуры ошибки, как это уже сделано в предоставленной части текста. -
Если данные внутри файла выглядят как текст, случайно добавленный в бинарный поток, попробуйте исправить файл, удалив первые байты, например:
tail -c+39 file.tar.gz > corrected.tar.gz
- После этого можно разархивировать исправленный файл командой:
gunzip < corrected.tar.gz | tar xvf -
- Проверьте, были ли данные успешно извлечены, и не содержат ли они временных меток
1970-01-01
, что может свидетельствовать о дополнительной порче данных.
Обратите внимание, что любой из шагов может потребовать индивидуальной корректировки в зависимости от того, что конкретно не так с вашим файлом. Эти шаги должны помочь идентифицировать и устранить проблему с некорректным архивом.
Заключение
Корректное использование командных утилит требует внимательности к синтаксису и пониманию их функционала. Даже небольшая ошибка в команде может привести к существенным проблемам при последующем извлечении данных. Если вы продолжаете сталкиваться с подобными проблемами, рекомендуется сохранять контрольные суммы файлов до и после архивирования для проверки целостности данных, а также использовать более современные и устойчивые форматы архивирования для критически важных данных.