← Весь справочник

tar

Упаковка каталогов в архив и распаковка — .tar, .tar.gz, .tar.xz, просмотр и выборочное извлечение

tar склеивает файлы и каталоги в один архив, сохраняя структуру, права, владельцев и время изменения. Сам по себе tar не сжимает — сжатие добавляется опцией: z (gzip, .tar.gz/.tgz), J (xz, .tar.xz).

Синтаксис

tar -c [опции] -f архив.tar файлы…     # создать
tar -t [опции] -f архив.tar [файлы…]   # показать содержимое
tar -x [опции] -f архив.tar [файлы…]   # распаковать

Режим выбирается ровно один. Опции можно склеивать: tar -czf = tar -c -z -f. Старая запись без дефиса (tar czf) тоже работает.

Режимы

РежимЧто делает
-cсоздать новый архив
-tпоказать список файлов в архиве
-xраспаковать
-rдописать файлы в конец архива (только несжатый .tar)
-uдописать файлы, которые новее своих копий в архиве (только .tar)
-Aдописать в архив содержимое другого .tar
--deleteудалить файлы из архива (только .tar)
-dсравнить архив с файлами на диске: что отличается

Архив и сжатие

ОпцияЧто делает
-f архивимя файла архива; -f - — stdout/stdin
-zgzip (.tar.gz, .tgz)
-Jxz (.tar.xz) — сильнее, но медленнее
-j / --zstdbzip2 / zstd — нужны одноимённые программы в системе
-aвыбрать сжатие по расширению имени архива (при создании)
-I 'команда'сжимать произвольной программой: -I 'gzip -9', -I 'xz -T0'

При чтении (-t, -x) сжатие можно не указывать: tar -xf архив.tar.xz определит его сам.

Какие файлы взять

ОпцияЧто делает
-C каталогперейти в каталог перед работой: откуда брать файлы или куда распаковать
--exclude='шаблон'не включать подходящие файлы и каталоги на любом уровне (ставь до списка файлов)
--anchoredследующие --exclude сравнивать с началом пути в архиве
-X файлшаблоны исключений из файла, по одному на строку
--exclude-vcsне включать .git, .svn и подобные
-T списоквзять имена файлов из файла (-T - — со stdin); с --null — разделённые нулевым байтом
--newer-mtime='2024-01-01'только файлы, изменённые после даты (каталоги попадают всегда)
-g снимокинкрементный архив: в следующий раз с тем же снимком попадут только изменения
-hкласть в архив файлы, на которые указывают ссылки, а не сами ссылки
--one-file-systemне переходить на другие файловые системы
--remove-filesудалить исходные файлы после упаковки
-Pсохранить абсолютные пути (ведущий /) — обычно не нужно

Как распаковать

ОпцияЧто делает
--strip-components=Nотрезать первые N уровней пути
--transform='s,^app,app-1.0,'переименовать пути выражением как в sed (работает и при создании)
--wildcardsразрешить шаблоны * в именах при -t/-x
-Oраспаковать в stdout, а не на диск
-kне перезаписывать существующие файлы (ошибка на каждом)
--skip-old-filesмолча пропускать существующие файлы
--keep-newer-filesне перезаписывать файлы, которые на диске новее
-mне восстанавливать время изменения — поставить текущее
-pвосстановить права точно, без учёта umask (для root включено по умолчанию)
--no-same-ownerне восстанавливать владельцев — всё будет принадлежать тебе

Владельцы в архиве и вывод

ОпцияЧто делает
-vпечатать имена файлов; -vv или -tv — подробно
--owner=root --group=rootзаписать в архив другого владельца
--numeric-ownerписать и читать владельцев только числами
--totalsв конце напечатать, сколько байт записано
-Wпосле создания проверить архив

Строка tar -tvf: права, владелец/группа, размер в байтах, дата и время изменения, путь. Для ссылок — имя -> цель.

-rw-r--r-- alice/devs     2048 2024-05-01 12:00 app/config.yml

Примеры

# упаковать каталог со сжатием gzip; пути в архиве начнутся с app/
tar -czf app.tar.gz -C /srv app

# архив с датой в имени
tar -czf "backup-$(date +%F).tar.gz" -C /srv app

# без лишнего: исключения — до списка файлов
tar -czf app.tar.gz --exclude=node_modules --exclude='*.log' --exclude-vcs -C /srv app

# посмотреть содержимое, не распаковывая (сжатие tar определит сам)
tar -tf app.tar.gz
tar -tvf app.tar.gz

# распаковать в указанный каталог (он должен существовать)
mkdir -p /tmp/restore && tar -xzf app.tar.gz -C /tmp/restore

# распаковать без верхнего каталога архива
tar -xzf app.tar.gz -C /srv/app --strip-components=1

# достать один каталог или файлы по шаблону
tar -xzf app.tar.gz app/logs
tar -xzf app.tar.gz --wildcards '*.conf'

# вывести один файл на экран
tar -xOf app.tar.gz app/config.yml

# сравнить архив с файлами на диске
tar -df app.tar.gz -C /srv

# упаковать список файлов, найденных find
find /etc -name '*.conf' -mtime -7 -print0 | tar -czf recent-conf.tgz --null -T -

# полный бэкап и затем только изменения
tar -czf full.tgz -g /var/backups/app.snar -C /srv app
tar -czf incr-1.tgz -g /var/backups/app.snar -C /srv app

# сильное сжатие xz во все ядра
tar -I 'xz -T0' -cf app.tar.xz -C /srv app

# архив через конвейер — например, сразу на другую машину
tar -czf - -C /srv app | ssh backup@example.com 'cat > app.tar.gz'

Подводные камни

  • -f должен стоять последним в склейке. За ним идёт имя архива: tar -cfz app.tar app создаст архив с именем z, а app.tar попытается упаковать как файл.
  • Абсолютные пути. tar -czf a.tgz /srv/app уберёт ведущий / и сохранит srv/app/… — при распаковке получится ./srv/app. Используй -C /srv app, чтобы в архиве был короткий путь.
  • --exclude после списка файлов не действует. GNU tar предупредит («has no effect») и упакует всё; при этом архив создастся, но код возврата будет ненулевым.
  • --exclude не привязан к началу пути. --exclude=cache исключит и app/cache, и app/lib/cache — любой компонент пути с таким именем. Чтобы исключить только app/cache, добавь --anchored перед --exclude=app/cache.
  • Шаблоны при распаковке. tar -xf a.tar '*.log' без --wildcards ищет файл с буквальным именем *.log и выдаёт «Not found in archive».
  • Распаковка перезаписывает файлы молча. Сначала посмотри список (-t), распаковывай в пустой каталог или добавь -k / --skip-old-files.
  • Сжатый архив нельзя изменить. -r, -u, -A, --delete работают только с несжатым .tar: «Cannot update compressed archives».
  • Пустой список файлов — ошибка «Cowardly refusing to create an empty archive». Так бывает, когда find для -T ничего не нашёл.
  • Владельцы. root при распаковке восстанавливает владельцев из архива. Обычный пользователь получает все файлы на себя.
  • bzip2 и zstd может не быть. tar -j и --zstd вызывают внешние программы и без них упадут с «not found».

См. также

gzip · rsync · find · split · ssh · date · checksums