Архивация и компрессия файлов. Часть 1
(НЕ является руководством по резервному копированию. Во второй части используется тот же тестовый каталог с теми же файлами.)
"АрхИв" (archive, "Акайв") в компьютерном смысле - набор файлов, подготовленный для длительного хранения. Предполагается, что файлами из архива какое-то время не будут пользоваться - подобно тому, как лишние вещи складывают в коробку и убирают в кладовку или ещё куда-то.
Цели архивАции файлов: иметь запасные копии; переслать несколько файлов/каталогов одной операцией; если нужно/возможно - сэкономить/высвободить место на диске. Для экономии места лишние файлы удаляют или "сжимают" (синонимы: "упаковывают", "подвергают компрессии").
Форматы архивов по сути - контейнеры: содержат "слепок" (snapshot) или "образ" (image) некоторой части дерева файловой системы или всего дерева (или даже больше). Важно, чтобы из архива можно было "разархивИровать" (извлечь) не только содержимое файлов, но и их имена/пути, даты, права и остальные нужные метаданные.
Традиционные и/или стандартные сейчас либо ранее (в POSIX) программы-архиваторы: cpio, pax, tar. Менее известные: dar, star.
Наиболее популярна - tar. Имя означает "tape archiver". Слово "tape" означает здесь - "[магнитная] лента". Устройства хранения на кассетах с магнитными лентами есть и сейчас, в основном в крупных организациях. Такое устройство называют "стрИмером" (streamer), а кассету - "кАртриджем" (cartridge). В отличие от магнитного диска, для операций чтения/записи ленту нужно перематывать; и создавать на ленте полноценную файловую систему (форматировать) обычно нецелесообразно. Поэтому здесь не достаточно простого копирования, а нужен формат-контейнер, файл которого пишется в символьный файл-устройство стримера сплошным потоком, хотя и условно разделён на блоки.
Примеры действий с архивами tar:
# Создать тестовый каталог с содержимым.
$ mkdir -p works/{today,old}
# Файл из нулей.
$ fallocate -l 100KiB works/old/file1.000
# Файл из случайно сгенерированных байтов.
$ dd if=/dev/urandom bs=1k count=100 of=works/old/file2.rnd
# Текстовый файл. Аргумент iflag=fullblock нужен,
# чтобы dd дождалась достаточного объёма данных от col,
# не завершаясь раньше этого.
$ man bash | col -b \
| dd bs=1k count=100 iflag=fullblock \
of=works/today/file3.txt
# Вот итоговый вид поддерева works от программы tree.
# (Она не стандартная, устанавливают отдельно.)
$ tree -F works/
works/
├── old/
│***├── file1.000
│***└── file2.rnd
└── today/
****└── file3.txt
(Редактор постов, как обычно, съел несколько пробелов, поэтому вместо них - звёздочки. Должно быть, разработчик редактора - любитель Пакмана.)
Предполагается заархивировать старые файлы, т. е. в old/.
Опции:
-c - создать архив;
-v - выводить список обрабатываемых файлов;
-f - архив не на ленте, а в указанном файле.
Всё остальное - архивируемые файлы/каталоги; для архивации поддерева будет достаточным указать только родительский каталог.
# Кавычки - просто выделение того, что именно идёт в архив.
$ cd works
$ tar -c -v -f archive.tar "old"
old/
old/file1.000
old/file2.rnd
# Посмотреть свойства архива:
# Формат.
$ file archive.tar
archive.tar: POSIX tar archive (GNU)
# Содержимое (список файлов).
$ tar -t -f archive.tar
old/
old/file1.000
old/file2.rnd
# Размер.
$ du -k archive.tar
212 archive.tar
# Освободить место, занятое старыми файлами.
$ rm -rv old/*
удалён 'old/file1.000'
удалён 'old/file2.rnd'
$ tree -F .
.
├── archive.tar
├── old/
└── today/
****└── file3.txt
# Извлечь содержимое архива.
# Сам архив останется прежним.
# Однобуквенные опции можно набрать слитно с общим дефисом.
$ tar -xvf archive.tar
old/
old/file1.000
old/file2.rnd
Опция -x - извлечь (скопировать) файлы из архива. Буква x - от extract. Если нужны только некоторые файлы, укажите их пути точно в том виде, в каком они записаны в архиве. В командном выражении пути файлов, извлекаемых из архива, указывают там, где при создании архива были указаны файлы, идущие в архив (то есть в конце).
Можно попробовать указать шаблоны имён с символами * и ?, но дополнительно нужна опция --wildcards, например:
$ tar -xv --wildcards -f archive.tar '*file?.???'
Файлы извлекаются вместе с путями, так что каталог old со всем содержимым мог быть восстановлен в любом другом подходящем рабочем каталоге.
Архив можно пополнить. Пополнение архивов бывает "добавлением" (append) или "обновлением" (update).
Если нужно добавить какие-то ещё файлы - опция -r вместо -c; и опять указать пути к файлам в конце командного выражения.
Если в том же каталоге появились новые файлы или поправлены старые, то это обновление (замена старых файлов на новые); вместо опции -c указать -u. Программа tar сама обнаружит и добавит в архив новые/исправленные файлы.
$ mv today/file3.txt old/
$ tar -uvf archive.tar "old"
old/file3.txt
$ tar -tf archive.tar
old/
old/file1.000
old/file2.rnd
old/file3.txt
Опция --delete - удалить файлы из архива (только если архив не на ленте):
# Всё равно этот файл состоял только из нулей.
# Здесь путь к файлу не выводится.
$ tar --delete -v -f archive.tar "old/file1.000"
$ tar -tf archive.tar
old/
old/file2.rnd
old/file3.txt
В архивах tar можно хранить несколько файлов с одинаковым путём. Выполняется повторными действиями добавления и обновления. В списке по -t очередь идёт снизу вверх, то есть сверху - архивированные последними. Опция --occurence=3 - выполнить действие над третьим по очереди добавления файлом из тех, что с одинаковым путём (нумерация начинается с единицы).
И ещё много разных опций, например:
-k - не извлекать файлы, если они уже есть в целевом каталоге;
--keep-newer-files - почти то же, но с уточнением, если уже имеющиеся в целевом каталоге файлы - более новые (по метаданным даты и времени), чем в архиве;
-p - метаданные о правах на файлы тоже восстанавливать из архива при извлечении;
--same-owner - восстанавливать имя владельца и группы;
-w - просить подтверждения на каждое действие.
Документация: man tar, info tar.
Благодаря сохранению метаданных, архиваторы иногда применяют для аккуратного копирования по конвейеру, например:
$ cd today
$ find . -depth -print0 | cpio --null -pvd ../old
../old/./file3.txt
Программа find часто служит генератором списка имён для архивации или иных массовых действий над файлами. Архиватор cpio всегда требует перенаправления: <, > или |. Опции -print0 и --null - для корректной обработки путей, содержащих кириллицу, пробелы и иные символы за пределами правила "8.3" и подобных ему ограничений.
Следите за тем, чтобы правильно строить пути (чтобы, например, не получилось в итоге works/old/today/file3.txt вместо works/old/file3.txt). Для начала стоит запустить только find.
Формат tar имеет проблемы с хранением специальных файлов, со скоростью поиска файла в архиве, с хранением некоторых метаданных. Если это критично, то следует применять архиватор dar.