архивирование файлов без временной метки

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

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

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

Как я могу создать архив (с помощью tar, zip или чего-то еще), который не включает информацию о времени?

Примечание: Я знаю, что даже если два tar-файла отличаются, я могу игнорировать их временные метки и сравнивать только их содержимое с помощью инструментов, таких как tar --diff или tarsum. Однако мне не разрешено использовать какие-либо внешние инструменты для сравнения (из-за моей настройки); я могу просто протестировать два архивных файла на точное равенство.

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

Пример:

$ mkdir copy1
$ touch copy1/file1
$ touch copy1/file2

$ sleep 60
$ mkdir copy2
$ touch copy2/file1
$ touch copy2/file2

$ ls -l copy1
total 0
-rw-r--r--  1 david  wheel  0 Oct 27 00:59 file1
-rw-r--r--  1 david  wheel  0 Oct 27 00:59 file2

$ ls -l copy2
total 0
-rw-r--r--  1 david  wheel  0 Oct 27 01:00 file1
-rw-r--r--  1 david  wheel  0 Oct 27 01:00 file2

# Содержимое этих файлов одинаково; они различаются только по своим временным меткам    

$ (cd copy1; tar -cvf ../copy1.tar .)
$ (cd copy2; tar -cvf ../copy2.tar .)

$ tar -tvf copy1.tar
drwxr-xr-x  0 david  wheel       0 Oct 27 00:59 ./
-rw-r--r--  0 david  wheel       0 Oct 27 00:59 ./file1
-rw-r--r--  0 david  wheel       0 Oct 27 00:59 ./file2

$ tar -tvf copy2.tar
drwxr-xr-x  0 david  wheel       0 Oct 27 01:00 ./
-rw-r--r--  0 david  wheel       0 Oct 27 01:00 ./file1
-rw-r--r--  0 david  wheel       0 Oct 27 01:00 ./file2

$ diff copy1.tar copy2.tar 
Бинарные файлы copy1.tar и copy2.tar отличаются

Я пробовал с zip -X вместо tar, но получаю тот же результат.

Даже если вы каким-то образом полностью отключите временные метки, я не был бы на 100% уверен, что это решит вашу проблему в каждом случае. Фактически, порядок файлов может изменить результаты (например, “tar cf a.tar file1 file2” отличается от “tar cf b.tar file2 file1”, но согласно вашей спецификации, содержимое одинаковое, а порядок может зависеть от файловой системы).

Я бы предложил вам сделать что-то более сложное, чем просто сравнение файлов, как вы сказали (md5sum и так далее).

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

for i in file1 file2; do echo "$i"; cat $i; done; 

Вы можете сжать его, если хотите. И будьте внимательны, чтобы всегда сохранять порядок.

Для сравнения содержимого архивов Zip вы можете использовать открытый инструмент comp_zip @ https://sourceforge.net/projects/unzip-ada/ или https://github.com/zertovitch/zip-ada/ .

Команда comp_zip file1.zip file2.zip; существуют параметры для подробного вывода.

Вы можете использовать опцию --mtime, чтобы установить явную временную метку:

$ tar --help
...
 Обработка атрибутов файлов:
...
      --mtime=ДАТА-ИЛИ-ФАЙЛ   установить mtime для добавленных файлов из ДАТА-ИЛИ-ФАЙЛ
...
$ tar --version
tar (GNU tar) 1.29
Copyright (C) 2015 Free Software Foundation, Inc.
Лицензия GPLv3+: GNU GPL версия 3 или более поздняя <http://gnu.org/licenses/gpl.html>.
Это бесплатное программное обеспечение: вы имеете право изменять и распространять его.
Гарантии НЕТ, в той мере, в какой это допускается законом.

Написано Джоном Гилмором и Джеем Фенласоном.

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

Архивирование файлов без временных меток

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

Проблема с временными метками

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

(cd copy1; tar -cvf ../copy1.tar .)
(cd copy2; tar -cvf ../copy2.tar .)

Результат будет таким, что архивы copy1.tar и copy2.tar будут отличаться, несмотря на идентичность их содержимого.

Решение с tar

Одним из решений этой проблемы является использование параметра --mtime, который позволяет установить временную метку для добавляемых файлов в архив. Чтобы избежать влияния временных меток, вы можете задать одну и ту же метку для всех файлов:

tar --mtime='1970-01-01' -cvf copy1.tar -C copy1 .
tar --mtime='1970-01-01' -cvf copy2.tar -C copy2 .

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

Альтернативное решение: использование zip

Если вас больше интересует использование zip, вы можете воспользоваться флагом -X, который исключает временные метки файлов из архивации. Однако, поскольку вы упомянули, что пробовали этот подход и он сработал не так, как ожидалось, важно убедиться, что вы правильно применяете команду:

zip -X copy1.zip -r copy1
zip -X copy2.zip -r copy2

Альтернативные способы без изменения временных меток

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

for file in copy1/*; do echo "$file"; cat "$file"; done > archive.txt

Это создаст один текстовый файл archive.txt, содержащий все файлы вместе с их именами.

Заключение

Таким образом, для достижения детерминистичного архивирования без влияния временных меток, вы можете использовать параметр --mtime в tar или использовать zip с флагом -X. Если же это не подходит, создание простого текстового файла с содержимым также может быть оптимальным решением.

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

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

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