Командная строка Linux, архивирование и сжатие: команды tar, gzip, bzip2, xz, zstd и zip, 7z, rar

Командная строка Linux, архивирование и сжатие: команды tar, gzip, bzip2, xz, zstd и zip, 7z, rar

Приветствую!

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

Подписывайтесь на наш телеграм @r4ven_me📱, чтобы не пропустить новые публикации на сайте😉. А если есть вопросы или желание пообщаться по тематике — заглядывайте в Вороний чат @r4ven_me_chat🧐.

Если вы новичок в мире Linux, то рекомендую изучить мои предыдущие статьи по командной строке:

Введение

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

В какой-то момент изучения Linux для меня стало открытием, что tar — это именно архиватор. Для сжатия он использует внешние утилиты, обычно называемые по формату сжатия: gzip, bzip2, xz или zstd. Разумеется, форматов существует гораздо больше, но по моему опыту именно эти применяются чаще всего.

Отдельно стоит упомянуть утилиты zip и 7z, которые умеют и архивировать, и сразу сжимать данные в свой собственный одноимённый формат.

Для пользователей Linux, которые регулярно имеют дело с Windows существует утилита rar (есть в стандартных non free репозиториях). Она является проприетарным ПО, однако для распаковки архивов используется open source утилита — unrar.

Все примеры из статьи выполнены среде дистрибутива Linux Mint 22 (Ubuntu 24.04).

На этом вводная часть завершена. Перейдём к списку команд, которые мы будем рассматривать.

Список команд

Итак, сегодня наш арсенал инструментов пополнится следующими командами-архиваторами:

УтилитаПолное названиеЧто делаетРасширениеОсобенности
tarTape ARchiveАрхивация.tarОткрытое ПО.
Архиватор, который только объединяет файлы, а для сжатия использует внешние утилиты (gzip, bzip2, xz, zstd).
7z7zipАрхивация + сжатие.7zОткрытое ПО.
Универсальный формат, одновременно архивирует и отлично сжимает.
zipот англ. zip («сжимать»)Архивация + сжатие.zipОткрытое ПО.
Универсальный формат, одновременно архивирует и сжимает, стандарт для Windows.
rarRoshal ARchiverАрхивация + сжатие.rarЗакрытое ПО.
Также популярен в Windows, хорошее сжатие, но ограничен лицензией; в Linux чаще используют unrar для распаковки.

И командами-утилитами сжатия:

УтилитаПолное названиеЧто делаетРасширениеОсобенности
gzipGNU ZipСжатие.gzОткрытое ПО.
Быстрое сжатие и распаковка, широко используется с tar для .tar.gz.
bzip2Burrows–Wheeler zip 2Сжатие.bz2Открытое ПО.
Даёт лучшее сжатие, чем gzip, но работает медленнее.
xzпросто «xz» (на базе LZMA2)Сжатие.xzОткрытое ПО.
Обеспечивает максимальное сжатие, но очень медленный при архивации и распаковке.
zstdZstandardСжатие.zstОткрытое ПО.
Современный алгоритм с отличным балансом скорости и качества сжатия.

Также для примерного понимания разницы форматов, ниже приведено субъективное сравнение их скорости работы и сжатия:

💡 Тема реального тестирование каждого формата достойна отдельной статьи.

Формат/командаАлгоритм(ы) сжатияСкорость сжатияСкорость распаковкиСтепень сжатия
gzipDeflateвысокаявысокаясредняя
bzip2Burrows-Wheeler transform (BWT)низкаясредняявысокая
xzLZMA2низкаянизкаяочень высокая
zstdLZ77 и ANSочень высокаяочень высокаяочень высокая
zipDeflate и другиесредняяочень высокаясредняя
7zLZMA и другиесредняявысокаяочень высокая
rarPPMdсредняявысокаявысокая

В статье сделан акцент на архиваторе на tar + утилиты сжатия, т.к. именно эта связка используется чаще всего для работы с архивами в Linux, в т.ч. и в Shell скриптах. Но я также покажу базовые команды работы с zip, 7z, и rar в конце статьи.

Подготовка

Почти всегда tar и утилита сжатия gzip предустановлены в системе, в отличие от других архиваторов/утилит. Если что-то необходимое отсутствует в вашей системе, всегда можно доустановить:

sudo apt update

sudo apt install -y tar gzip bzip2 xz-utils zstd zip 7z rar

⚠️ Еще раз подчеркну, что утилита rar является проприетарным ПО и доступна в репозитории non-free.

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

dd if=/dev/urandom of=./file1 bs=50K count=10

dd if=/dev/urandom of=./file2 bs=50K count=10

mkdir -v ./dir/

cp -v ./file1 ./file2 ./dir/

💡 Команда dd в примере выше использует специальное псевдоустройство urandom для генерации псевдослучайных данных в размере 500 кб и сохраняет их в указанный файл.

Готово, переходим к созданию архивов.

Архивация с помощью tar

Т.к. tar довольная старая программа, она поддерживает ключи в классическом Unix стиле, т.е. без знака дефиса перед ключом. Чтобы не запутать читателя я буду использовать типичные на сегодня ключи с дефисом😌.

Итак, основные команды tar.

Синтаксис:

tar [опции] <имя_архива> <файлы_или_директории>

Чтобы не допускать синтаксических ошибок, с чем часто сталкиваются новички, необходимо понимать, что командная строка Linux оперирует 3-мя типами параметров: флаги: -f1 --flag2, именованные параметры --arg value и позиционные аргументы: arg1 arg2 arg3. Путаница возникает тогда, когда параметры комбинируют, например, флаги с именованными параметрами — в таком случае важен их порядок.

Источник: betterdev.blog

Держа в голове эту информацию приступаем к изучению команд tar.

Создать архив:

tar -c -f ./archive.tar ./file1 ./file2 ./dir/

Команда создаёт архив arhcive.tar с перечисленными в конце файлами/директорией в текущем каталоге.

💡 -c (--create) — флаг, который указывает архиватору создать архив, затем именованным параметром -f (--file) указывается местоположение и имя файла-архива. В самом конце перечисляются позиционные аргументы: файлы/папки, которые нужно добавить в архив (пробел в качестве разделителя).

Типичным расширением для tar архивов является: .tar.

Добавив флаг -v (--verbose) tar будет построчно выводить добавляемые в архив файлы:

tar -v -c -f ./archive.tar ./file1 ./file2 ./dir/

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

💡 Ключ -C указывает tar изменить рабочую директорию. Для лучшего понимания, представьте что tar перед упаковкой архива выполняет cd /path/to/dir и уже там выполняет указанную операцию.

Например, следующая команда добавит в архив все файлы из директории /tmp/dir/:

cp -r ./dir/ /tmp/

tar -C /tmp/dir/ -c -f ./archive.tar ./

Относительный путь ./ указанный в конце говорит tar‘у добавить в архив все файлы текущей директории, которую мы изменили с помощью -C (/tmp/dir/ в примере выше).

Важно понимать,что tar записывает в архив путь к файлу ровно в том виде, как он был передан: относительные пути сохраняются, абсолютные — только если явно разрешены (--absolute-names). По умолчанию / в начале пути убирается. При распаковке создаются те же каталоги и файлы.

Извлечь архив:

tar -x -f ./archive.tar

💡 -x (--extract) — извлечь, -f — имя архива.

Данная команда разархивирует archive.tar в текущую директорию.

❗ Имейте в виду, что если в директории, в которую вы извлекаете файлы из архива, есть файлы с идентичными именами/путями, то tar перезапишет их.

Чтобы изменить директорию куда нужно распаковать архив также используйте ключ -C или --directory:

tar -C /tmp/dir/ -x -f ./archive.tar

Просмотреть содержимое:

tar -t -f ./archive.tar

💡 -t (--list) — вывести содержимое списком, -f — имя архива.

К слову, с помощью ключа -t обычно проверяют архив на отсутствие повреждений в структуре файла. Пример:

tar -t -f ./archive.tar &> /dev/null

Если архив поврежден — команда завершится ошибкой.

Добавить файл в существующий архив:

tar -r -f ./archive.tar /etc/passwd

💡 -r (--append) — добавить к существующему НЕ СЖАТОМУ архиву, -f — имя архива. Если архив сжат (.tar.gz, .tar.xz, .tar.zst и т.д.), команда не сработает — сначала нужно «разжать» архив, добавить файл и вновь сжать его.

Проверяем:

tar -t -f ./archive.tar

Как видим tar убрал / из пути к добавленному файлу, чей путь начинается с корня.

Удаление файла из архива:

tar --delete -f archive.tar etc/passwd

💡 --delete — удалить указанный в конце файл из архива, -f — имя архива. В случае сжатых архивов ситуация аналогичная добавлению файлов: разжать, удалить, сжать.

Проверяем, что файл удалился из архива:

tar -t -f ./archive.tar

Сжатие tar архива

Все это хорошо, но архив без сжатия, все равно что бутерброд с колбаской, но без сыра😋.

Ключи без дефиса🙄

Важно отметить, что команда tar имеет специальные ключи для сжатия архива с помощью разных форматов/алгоритмов. Благодаря этому для пользователя всё выглядит прозрачно. Но если в системе отсутствует соответствующая утилита (например, xz), то команда tar завершится с ошибкой.

Сжатие сразу при архивировании

  • Gzip:
tar -c -z -f ./archive.tar.gz ./file1 ./file2

💡 -z — использовать gzip.

Обратите внимание, что общепринятым расширением для сжатых gzip файлов является .gz. И т.к. tar лишь создает архив (tarball), а сжимает внешняя утилита: указывается двойное расширение .tar.gz. Некоторым такой вид не очень нравится (в т.ч. мне), поэтому существует еще одно, общепринятое расширение для таких файлов: .tgz.

Давайте для сравнения создадим аналогичный архив без сжатия и узнаем размеры архивов с помощью утилиты du (disk usage):

tar -c -f ./archive.tar ./file1 ./file2

du -sh ./archive.t*

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

Для наглядности давайте создадим файл размером 50 мб и наполним его нулями. После чего создадим обычный архив и сжатый, чтобы увидеть разницу в размере:

dd if=/dev/zero of=./file50m bs=5M count=10

tar -c -f ./archive50m.tar file50m

tar -c -z -f ./archive50m.tgz file50m

du -sh ./archive50m.t*

Разница налицо! Но это потому что файлы заполнен нулями и такое хорошо сжимается. Как и любой текст. Этим примером я хотел показать вам, что сжатие может быть не оправдано с точки зрения утилизации ресурсов сервера, особенно при работе с большими файлами.

Чтобы наглядно увидеть разницу в форматах давайте создадим пару текстовых файлов:

yes "The quick brown fox jumps over the lazy dog" | head -n 1000000 > ./file1.txt

yes "Съешь же ещё этих мягких французских булок, да выпей чаю" | head -n 1000000 > ./file2.txt

💡 yes «…» — бесконечно печатает одну и ту же строку; head -n 1000000 — ограничивает до 1 млн строк. В итоге получится файл ~45 МБ с повторяющимся текстом.

Создадим tar архив и сожмём его с помощью gzip:

tar -c -z -f ./archive.tar.gz ./file1.txt ./file2.txt

И других форматов:

  • Bzip2:
tar -c -j -f archive.tar.bz2 ./file1.txt ./file2.txt

💡 -j — сжимать с помощью bzip2.

  • Xz:
tar -c -J -f archive.tar.xz ./file1.txt ./file2.txt

💡 -J — сжимать с помощью xz.

  • Zstd
tar -c --zstd -f archive.tar.zst ./file1.txt ./file2.txt

💡 --zstd — сжимать с помощью zstd.

Давайте посмотрим на результат:

du -sh ./archive.tar.*
40K     ./archive.tar.bz2
468K    ./archive.tar.gz
24K     ./archive.tar.xz
16K     ./archive.tar.zst

zstd не только сжал лучше остальных, но еще и сделал это молниеносно, особенно в сравнении с bzip2.

Извлечение работает аналогично, tar сам определяет метод сжатия:

tar -x -f ./archive.tar.gz
tar -x -f ./archive.tar.bz2
tar -x -f ./archive.tar.xz
tar -x -f ./archive.tar.zst

Стоит также отметить возможность явного указания команды сжатия архива tar с помощью ключа -I. Пример:

tar -v -I "zstd -19" -c -f ./archive.tzst ./file1.txt ./dir

Тут мы сразу указали и степень сжатия 😏.

Сжатие одиночных файлов

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

Утилита gzip

Синтаксис:

gzip [опции] <имя_сжимаемого_файла>

Примеры:

  • Сжать файл:
gzip ./file1.txt

💡 Создаст file.txt.gz и удалит исходный.

  • Разжать файл:
gunzip ./file1.txt.gz
#или
gzip -d ./file1.txt.gz

💡 -d — decompress.

  • Сжать файл без удаления оригинала:
gzip -k ./file1.txt

Можно указать степень сжатия: по умолчанию уровень = 6 (баланс между скоростью и размером), максимум = 9:

gzip -9 ./file1.txt

Чем выше уровень, тем лучше сжатие, но медленнее скорость.

Утилита bzip2

Работает как gzip, но обычно лучше сжимает, хоть и медленнее.

Синтаксис:

bzip2 [опции] <имя_сжимаемого_файла>

Примеры:

  • Сжать:
bzip2 ./file1.txt

💡 Создаст file.txt.bz2 и удалит исходный.

  • Разжать:
bunzip2 ./file1.txt.bz2
# или
bzip2 -d ./file1.txt.bz2
  • Сжать без удаления оригинала:
bzip2 -k ./file1.txt
  • Уровни сжатия: по умолчанию = 6, максимум = 9:
bzip2 -9 ./file1.txt

Утилита xz

Современный алгоритм сжатия, чаще всего эффективнее gzip и bzip2, но медленнее 🐌.

Синтаксис:

xz [опции] <имя_сжимаемого_файла>

Примеры:

  • Сжать:
xz ./file1.txt

💡 Создаст file1.txt.xz и удалит исходный.

  • Разжать:
unxz ./file1.txt.xz
# или
xz -d ./file1.txt.xz
  • Сжать без удаления оригинала:
xz -k ./file1.txt
  • Уровни сжатия: по умолчанию = 6, максимум = 9:
xz -9 ./file1.txt

Утилита zstd

zstd — современный алгоритм сжатия от одной запрещенной организации🙈.
Он быстрее, чем gzip/bzip2/xz, и при этом даёт отличное сжатие👍. Подходит как для архивов, так и для потокового сжатия (например, в systemd, tar, rsync).

Синтаксис:

zstd [опции] [имя_сжимаемого_файла]

Примеры:

  • Сжать файл:
zstd ./file1.txt

💡 Создаст file1.txt.zst и удалит оригинал.

  • Сжать файл без удаления оригинала:
zstd -k ./file1.txt
  • Разжать:
unzstd ./file1.txt.zst
#или
zstd -d ./file1.txt.zst
  • Управление степенью сжатия: по умолчанию уровень = 3, максимум = 19:
zstd -19 ./file1.txt

Архивирование и сжатие потоков данных

Если вы не знаете или плохо понимаете, что это такое, то крайне рекомендую мою вводную статью по этой теме:
🔗 Командная строка Linux, перенаправление ввода и вывода: операторы «>», «<«, «|»

P.S. Не нашел мем про stdin/stdout, поэтому картинку сгенерила нейронка. Немного перебор, но меня рассмешило😂😂

Создание архива (базовые операции)

  • Создание архива с выводом в stdout и перенаправлением его в файл:
tar -c -f - ./file1 ./file2 ./dir/ > ./archive.tar

💡 Обратите внимание, что в именованном параметре, который определяет выходной «файл» (-f), в качестве значения указывается символ дефиса -. В Linux дефис является общепринятым идентификатором использования стандартных потоков.

  • Тоже самое, только с сжатием gzip (-z):
tar -c -z -f - ./file1 ./file2 ./dir/ > ./archive.tgz
  • Архивация в stdout и передача по конвейеру внешней утилите сжатия (на примере gzip) с последующим перенаправлением в файл:
tar -c -f - ./file1 ./file2 ./dir/ | gzip -9 > ./archive.tgz

Создание архива через поиск файлов

  • Поиск файлов по шаблону с помощью find и последующей передачей списка найденных файлов через stdout в tar для создания архива:
find ./ -name 'file[1-2]' | tar -c -z -f ./archive.tgz -T -

💡 Обратите внимание, что тут дефис используется в качестве позиционного аргумента, который определяет список архивируемых файлов. Ключ -T (или --files-from) говорит tar‘у брать список файлов из stdin.

find в команде выше ищет все файлы с именем file1 и file2 в текущей директории и её поддиректориях.

Работа с удаленным сервером (🔗 SSH)

  • Отправка архива в stdout с помощью локального tar с последующей передачей потока по конвейеру утилите ssh, которая в свою очередь передает поток tar‘у на удалённом хосте, а он уже читает stdin как архив и распаковывает его в директории /tmp:
tar -c -z -f - ./dir/ | ssh ivan@test.r4ven.me "tar -C /tmp -x -z -f -"
  • Создание архива на удаленном сервере с помощью ssh и выводом его в локальный stdout, который перенаправляется в локальный файл:
ssh ivan@test.r4ven.me "tar -c -z -f - ./file1 ./file2" > ./archive.tgz
  • Передача архива с помощью cat с удалённого хоста в локальный stdin, с последующим разархивированием его с помощью локального tar на локальной машине в директорию /tmp:
ssh ivan@test.r4ven.me "cat ./archive.tgz" | tar -C /tmp -x -z -f -

Шифрование

  • Создание сжатого архива в stdout и отправка его по конвейеру утилите шифрования gpg и перенаправление в указанный файл:
tar -c -z -f - ./file1 ./file2 ./dir/ | gpg --batch --symmetric --passphrase "MyPassword" > ./archive.tgz.gpg
  • Расшифровка файла (для расшифровки gpg запросит пароль) в stdout с передачей по конвейеру в tar для последующей распаковки:
gpg -d ./archive.tgz.gpg | tar -x -z -f -

Разбиение на части

  • Создание архива в stdout с передачей потока утилите split, которая разбивает архив на части указанного размера:
tar -c -z -f - ./dir/ | split -b 200K - ./archive.tgz.part-
  • Объединение частей архива с помощью cat с последующей распаковкой уже с помощью tar:
cat ./archive.tgz.part-* | tar -x -z -f -

Альтернативные архиваторы: zip, 7z, rar

Архиватор zip

zip — универсальный архиватор (и сжимает, и архивирует), популярен в Windows.

Синтаксис:

zip [опции] <имя_архива> <файлы_или_директории>

Примеры:

  • Создание архива:
zip ./archive.zip ./file1 ./dir/
  • Распаковка:
unzip ./archive.zip
  • Список содержимого:
unzip -l ./archive.zip

💡 -l = list (показать список файлов).

  • Добавить файл в архив:
zip ./archive.zip ./file2
  • При создании архива можно указать уровень сжатия:
zip -0 ./archive.zip ./file1.txt # без сжатия (только упаковка)

zip -9 ./archive.zip ./file1.txt # максимальное сжатие

Архиватор 7z (7-Zip)

Архиватор с отличной степенью сжатия. Утилиты: 7z или 7za (из пакета p7zip).

Синтаксис:

7z <операция> <имя_архива> <файлы_или_директории>

Примеры:

  • Создание архива:
7z a ./archive.7z ./file1 ./dir/

💡 a = add (добавить в архив).

  • Распаковка архива:
7z x ./archive.7z

💡 x = extract с сохранением структуры каталогов.

  • Просмотр содержимого:
7z l ./archive.7z

💡 l = list (показать список файлов).

  • Добавление файлов в архив:
7z a ./archive.7z ./file2

💡 a = add (добавить).

  • Указать уровень сжатия:
7z a -mx=0 archive.7z ./file1.txt # без сжатия

7z a -mx=9 archive.7z ./file1.txt # максимальное сжатие

Архиватор rar

Также популярный архиватор. Известен тем, что принес своему разработчику баснословное количество… денег словесных благодарностей👏. Используется одноименная утилита rar — проприетарная. Для распаковки обычно используется unrar (open source).

Синтаксис:

rar <операция> <имя_архива> <файлы_или_директории>

Примеры:

  • Создание архива:
rar a ./archive.rar ./file1 ./dir/

💡 a = add (добавить).

  • Распаковка архива:
unrar x ./archive.rar

💡 x = extract с сохранением структуры каталогов.

  • Просмотр содержимого:
unrar l ./archive.rar

💡 l = list (показать список файлов).

  • Добавление файлов в архив:
rar a ./archive.rar ./file2

💡 a = add (добавить).

Утилита rar тоже позволяет выбрать степень сжатия:

rar a -m0 ./archive.rar file1.txt # без сжатия

rar a -m5 archive.rar file1.txt   # максимальное сжатие

Простой тест для сравнения

Сжимаем:

zip -9 ./archive.zip ./file* ./dir

7z a -mx=9 archive.7z ./file* ./dir

rar a -m5 ./archive.rar ./file* ./dir

tar -I "zstd -19" -cvf ./archive.tzst ./file* ./dir

Смотрим размер:

du -s ./archive.*

Итог:

1008  ./archive.7z
2004  ./archive.rar
2008  ./archive.tzst
1128  ./archive.zip

zstd отработал быстрее всех, но лучшее сжатие отнюдь не у него🤔. Вероятно под разные наборы файлов эффективнее работает тот или иной формат🤷‍♂️. Определять рекомендуется опытным путём👨‍💻.

В следующей раз мы напишем бэкап скрипт на Bash, который будет выполнять архивирование файлов по расписанию📋. Не пропустите😉.

Не забывайте про нашу телегу📱и чат💬
Всех благ✌️

That should be it. If not, check the logs 🙂

Полезные материалы

Подписаться
Уведомить о
1 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии