Как проверить, является ли файл Unix .tar.gz допустимым файлом, не распаковывая его?

Ответы:

122

Как насчет того, чтобы просто получить листинг архива и выбросить результат, а не распаковывать файл?

tar -tzf my_tar.tar.gz >/dev/null

Отредактировано согласно комментарию. Спасибо, зрайм!

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

Роб Уэллс
источник
13
Зачем использовать, -vесли вы просто подключаете вывод /dev/null?
zrajm
2
Правда @zrajm. Думаю, это моя мышечная память! (-:
Роб Уэллс
5
-zОпция также ненужная. Он ничего не делает в режиме извлечения или списка.
asmeurer
1
@asmeurer Re: -zЭто определенно относится к GNU tar - знаете ли вы, верно ли это в других местах (BSD и т. д.)?
belacqua
2
@bobwells Но подразумевает ли успешная распаковка или перечисление файлов содержимого целостность данных tar.gz? Любая информация о поддержке?
Frozen Flame
99

вы, вероятно, могли бы использовать параметр gzip -t для проверки целостности файлов

http://linux.about.com/od/commands/l/blcmdl1_gzip.htm

из: http://unix.ittoolbox.com/groups/technical-functional/shellscript-l/how-to-test-file-integrity-of-targz-1138880

Чтобы проверить, не поврежден ли файл gzip:

gunzip -t file.tar.gz

Чтобы проверить, не поврежден ли tar-файл внутри:

gunzip -c file.tar.gz | tar -t > /dev/null

В рамках резервного копирования вы, вероятно, могли бы просто запустить последнюю команду и проверить значение $? затем для значения 0 (успех). Если есть проблема с tar или gzip, $? будет иметь ненулевое значение.

Джон Бокер
источник
3
И bzip2 -t file.bz2для файлов bz2.
asmeurer
4
Разве это не использование двух команд для выполнения того, что делает tar -tzf my_tar.tar.gz> / dev / null?
Роб Уэллс
Разве это не должно быть tar -t > /dev/null(примечание: tvs -t)?
Intrastellar Explorer
1
@IntrastellarExplorer, это опечатка с моей стороны, хотя он должен работать без дефиса. Я просто привык к старым вариантам на tar. unix.stackexchange.com/questions/394060/…
Джон Бокер
32

Если вы хотите сделать настоящий тестовый извлечение файла tar без извлечения на диск, используйте параметр -O. Это выводит экстракт на стандартный вывод вместо файловой системы. Если файл tar поврежден, процесс будет прерван с ошибкой.

Пример неудачного теста на шарик смолы ...

$ echo "this will not pass the test" > hello.tgz
$ tar -xvzf hello.tgz -O > /dev/null
gzip: stdin: not in gzip format
tar: Child returned status 1
tar: Error exit delayed from previous errors
$ rm hello.*

Рабочий пример ...

$ ls hello*
ls: hello*: No such file or directory
$ echo "hello1" > hello1.txt
$ echo "hello2" > hello2.txt
$ tar -cvzf hello.tgz hello[12].txt
hello1.txt
hello2.txt
$ rm hello[12].txt
$ ls hello*
hello.tgz
$ tar -xvzf hello.tgz -O
hello1.txt
hello1
hello2.txt
hello2
$ ls hello*
hello.tgz
$ tar -xvzf hello.tgz
hello1.txt
hello2.txt
$ ls hello*
hello1.txt  hello2.txt  hello.tgz
$ rm hello*
Осси Мур
источник
1
Мне кажется, что это лучший тест. Он действительно извлекает каждый файл и проверяет отсутствие ошибок.
рукава
Действительно полезно. Я создал сценарий оболочки, добавил обработчик аргументов, чтобы передать путь к файлу и поместить его в свой путь :) [tar -xvzf $ 1 -O> / dev / null]
smonff
@sleeves Как вы думаете, почему он лучше принятого ответа? tar -tvzf hello.tgz> / dev / null также дает ту же ошибку.
dash17291 04
5
@ dash17291 Я говорю это, потому что ожидаю, что будет сложной задачей доказать, что во всех случаях -tvf перехватит все ошибки или искажения, указанные в -xvf. Другими словами, -xvf перехватит все это -tvf, но я не могу сказать, что верно обратное.
рукава
Возможно, вам стоит использовать и > /dev/nullдля рабочего примера.
moi
12

Вы также можете проверить содержимое файла * .tag.gz с помощью pigz(parallel gzip), чтобы ускорить проверку архива:

pigz -cvdp number_of_threads /[...]path[...]/archive_name.tar.gz | tar -tv > /dev/null
эйн
источник
Мини-тест: запуск с pigz -cvd: 80s, при запуске с принятым ответом tar -tzv: 143s в архиве 22G.
Вадих М.
как удалить уведомление из cronjob о «tar: удаление начального символа« / »из имен членов» при использовании этого метода?
MaXi32,
3

Я пробовал следующую команду, и они хорошо работают.

bzip2 -t file.bz2
gunzip -t file.gz

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

Шичэн Го
источник
2

Хороший вариант - использовать tar -tvvf <filePath> который добавляет строку, сообщающую о типе файла.

Пример в действительном файле .tar:

> tar -tvvf filename.tar 
drwxr-xr-x  0 diegoreymendez staff       0 Jul 31 12:46 ./testfolder2/
-rw-r--r--  0 diegoreymendez staff      82 Jul 31 12:46 ./testfolder2/._.DS_Store
-rw-r--r--  0 diegoreymendez staff    6148 Jul 31 12:46 ./testfolder2/.DS_Store
drwxr-xr-x  0 diegoreymendez staff       0 Jul 31 12:42 ./testfolder2/testfolder/
-rw-r--r--  0 diegoreymendez staff      82 Jul 31 12:42 ./testfolder2/testfolder/._.DS_Store
-rw-r--r--  0 diegoreymendez staff    6148 Jul 31 12:42 ./testfolder2/testfolder/.DS_Store
-rw-r--r--  0 diegoreymendez staff  325377 Jul  5 09:50 ./testfolder2/testfolder/Scala.pages
Archive Format: POSIX ustar format,  Compression: none

Поврежденный файл .tar:

> tar -tvvf corrupted.tar 
tar: Unrecognized archive format
Archive Format: (null),  Compression: none
tar: Error exit delayed from previous errors.
Diegoreymendez
источник
Это происходит с tar BSD, но не с tar GNU.
mcallister
1

Все это очень неоптимальные решения. Из спецификации GZIP

ID2 (IDentification 2)
Они имеют фиксированные значения ID1 = 31 (0x1f, \ 037), ID2 = 139 (0x8b, \ 213), чтобы идентифицировать файл как находящийся в формате gzip.

Должен быть закодирован на любом языке, который вы используете.

Кевин Лю
источник
если файл был усечен, для его обнаружения потребуется полная декомпрессия
philwalk
0

> используйте параметр -O. [...] Если файл tar поврежден, процесс будет прерван с ошибкой.

Иногда да, а иногда нет. Давайте посмотрим на пример поврежденного файла:

echo Pete > my_name
tar -cf my_data.tar my_name 

# // Simulate a corruption
sed < my_data.tar 's/Pete/Fool/' > my_data_now.tar
# // "my_data_now.tar" is the corrupted file

tar -xvf my_data_now.tar -O

Это показывает:

my_name
Fool  

Даже если вы выполните

echo $?

tar сказал, что ошибки не было:

0

но файл был поврежден, теперь в нем "Дурак" вместо "Пит".

Sys
источник
Люди редко используют tar-файлы без сжатия. Думаю, ваше замечание касается только несжатых файлов.
Jarekczek
6
Вы путаете честность с коррупцией. Ваш файл потерял целостность, но это все еще приемлемый формат архива.
Фил