Материал открыт для чтения

Войдите, чтобы сохранять прогресс и результаты.

Войти
Linux: Старт в терминале

Wildcards, glob-паттерны, tar и архивы

чтение ~9 минУрок 14 из 18

Wildcards, glob-паттерны и архивы

module linux start Image05

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


Wildcards и glob-экспансия

Shell умеет раскрывать шаблоны имён файлов до запуска команды. Это называется glob-экспансией.

Когда ты пишешь:

ls *.log

команда ls обычно не получает строку *.log. Сначала shell ищет в текущей директории подходящие файлы, например app.log, error.log и access.log.

И уже потом запускает:

ls app.log error.log access.log

Это важная мысль: wildcard раскрывает оболочка, а не сама команда. Поэтому glob работает с ls, cp, mv, rm, cat и другими командами, которые принимают пути к файлам.


Основные символы glob

Символ Значение Пример
* Любое количество символов, включая ноль *.log - все имена, заканчивающиеся на .log
? Ровно один любой символ data?.txt - data1.txt, но не data10.txt
[abc] Один символ из набора file[123].txt - file1.txt, file2.txt, file3.txt
[a-z] Один символ из диапазона [a-z]*.txt - имя начинается со строчной буквы
[0-9] Одна цифра app[0-9].log - app1.log, но не app12.log

Примеры:

ls /var/log/*.log
ls data?.txt
ls [aA]pp*.conf
cp *.conf /root/configs/
mv /root/configs/*.conf /root/old_configs/

* шире, чем ?. Паттерн app*.log подходит к app.log, app1.log и app12.log. Паттерн app?.log требует ровно один символ между app и .log, поэтому app12.log не подойдёт.


Скрытые файлы и отсутствие совпадений

Обычный * не подхватывает скрытые файлы, имена которых начинаются с точки.

ls *

не покажет .env. Чтобы явно обратиться к скрытым файлам, нужен шаблон с точкой:

ls .*

или обычный ls -a, если задача именно посмотреть список:

ls -la

Если glob не нашёл совпадений, поведение зависит от настроек shell. В обычном bash шаблон часто остаётся как есть, и команда получает буквальную строку:

ls *.missing
# ls: cannot access '*.missing': No such file or directory

Это не значит, что ls "не умеет wildcard". Это значит, что shell не нашёл файлов, подходящих под шаблон.


Brace expansion: фигурные скобки

Brace expansion похожа на wildcard, но работает иначе: shell не ищет существующие файлы, а просто генерирует строки.

mkdir -p /opt/project/{src,tests,docs}

Shell превратит это в:

mkdir -p /opt/project/src /opt/project/tests /opt/project/docs

Другие примеры:

touch log_{01..10}.txt        # создать log_01.txt, log_02.txt ... log_10.txt
cp file.txt{,.bak}            # скопировать file.txt в file.txt.bak
mkdir -p app/{config,logs,tmp} # создать app/config, app/logs и app/tmp

Разница:

  • *.log зависит от реально существующих файлов;
  • {src,tests,docs} не проверяет существование, а просто создаёт варианты текста.

Когда нужны кавычки

Кавычки запрещают shell раскрывать wildcard. Это нужно, когда шаблон должен получить сама команда.

Например, find должен сам искать имена по шаблону:

find /opt/devops/lab7 -name "*.txt"

Если написать без кавычек:

find /opt/devops/lab7 -name *.txt

shell может раскрыть *.txt в текущей директории ещё до запуска find. В результате find получит не шаблон, а список файлов или ошибочную форму аргументов.

Практическое правило:

  • для ls *.log, cp *.conf dest/, mv *.conf dest/ кавычки обычно не нужны, потому что раскрытие делает shell;
  • для find -name "*.log" кавычки нужны, потому что шаблон должен обрабатывать find.

Glob против find

Обычный glob работает в текущей директории или в явно указанном уровне пути:

ls /opt/devops/lab7/*.txt

Это найдёт .txt только прямо внутри /opt/devops/lab7, но не во вложенных директориях.

Для рекурсивного поиска по дереву чаще используют find:

find /opt/devops/lab7 -type f -name "*.txt"

find обойдёт /opt/devops/lab7 и все поддиректории. Поэтому для "все файлы во всех вложенных папках" выбирай find, а для "все файлы рядом" достаточно glob.


Осторожность с wildcard и rm

Wildcard удобно применять с cp и mv, но с rm он требует внимания.

rm *.log

Эта команда удалит все подходящие .log файлы в текущей директории. Перед удалением лучше сначала посмотреть, что именно раскроется:

ls -la *.log

Тот же принцип работает для перемещения:

ls -la /root/configs/*.conf
mv /root/configs/*.conf /root/old_configs/

Сначала проверка списка, потом действие.


Архив и сжатие: разные задачи

Архивирование и сжатие часто путают.

Архивирование объединяет много файлов и директорий в один файл-контейнер.

Сжатие уменьшает размер данных.

tar изначально архивирует: собирает много файлов в один .tar. gzip сжимает один файл. Вместе они дают распространённый формат .tar.gz: сначала собрать файлы через tar, потом сжать gzip.

directory/ -> tar -> backup.tar -> gzip -> backup.tar.gz

Поэтому gzip /etc/nginx/ не подходит для бэкапа директории: gzip работает с одним файлом, а не с деревом файлов. Для директории нужен tar.


tar: создать архив

Базовая команда создания архива:

tar cf backup.tar /opt/project/

Флаги:

  • c - create, создать архив;
  • f - file, дальше идёт имя файла архива.

Создать сжатый gzip-архив:

tar czf backup.tar.gz /opt/project/

Здесь добавился флаг z: сжать через gzip.

С подробным выводом:

tar czvf backup.tar.gz /opt/project/

v означает verbose: показывать файлы по мере добавления. В скриптах v часто убирают, чтобы вывод был короче.

Практически полезное правило: когда используешь короткие флаги czf, имя архива идёт сразу после группы флагов, потому что f ожидает файл архива:

tar czf /root/backup.tar.gz /opt/devops/lab8/src/

tar: посмотреть содержимое

Перед распаковкой архива полезно посмотреть, что внутри:

tar tf backup.tar
tar tzf backup.tar.gz

Флаги:

  • t - list, показать содержимое;
  • z - архив с gzip-сжатием;
  • f - имя архива.

Пример:

tar tzf /root/backup.tar.gz > /root/archive_list.txt

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


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

Распаковать .tar.gz в текущую директорию:

tar xzf backup.tar.gz

Флаг x означает extract.

Распаковать в конкретную директорию:

mkdir -p /root/extracted
tar xzf backup.tar.gz -C /root/extracted

-C задаёт целевую директорию для извлечения. Директория должна существовать заранее, поэтому перед этим часто делают mkdir -p.

Извлечь один файл:

tar xzf backup.tar.gz opt/project/config.txt

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


gzip и gunzip

gzip сжимает один файл и по умолчанию заменяет его на версию с .gz:

gzip large_file.txt
# large_file.txt исчез, появился large_file.txt.gz

Если нужно сохранить исходник:

gzip -k large_file.txt

Распаковка:

gunzip large_file.txt.gz
gzip -d large_file.txt.gz

Обе команды вернут исходный файл и уберут .gz-версию, если не указаны дополнительные флаги.

Посмотреть сжатый текст без распаковки на диск:

zcat large_file.txt.gz
zless large_file.txt.gz

zless особенно удобен для больших сжатых логов.


zip и unzip

В Linux чаще используют .tar.gz, но .zip встречается при обмене файлами с Windows и macOS.

zip -r archive.zip /opt/project/
unzip archive.zip
unzip -l archive.zip
unzip archive.zip -d /tmp/extract/
  • zip -r рекурсивно упаковывает директорию;
  • unzip -l показывает содержимое без распаковки;
  • unzip -d задаёт директорию назначения.

Для серверных бэкапов и Linux-пакетов чаще выбирай tar.gz, для передачи пользователям может быть удобнее zip.


Частые сценарии

Сделать бэкап конфигов nginx с датой в имени:

tar czf /root/nginx_backup_$(date +%Y%m%d).tar.gz /etc/nginx/

Посмотреть, что внутри:

tar tzf /root/nginx_backup_20260512.tar.gz

Распаковать в отдельную директорию, не смешивая с текущими файлами:

mkdir -p /tmp/nginx_restore
tar xzf /root/nginx_backup_20260512.tar.gz -C /tmp/nginx_restore

Скопировать проект через tar-поток:

tar czf - /opt/project/ | tar xzf - -C /srv/

Здесь - означает stdout или stdin вместо файла. Первая команда создаёт архив в поток, вторая сразу читает этот поток и распаковывает. Такой приём встречается в администрировании, но на старте важнее уверенно освоить обычные tar czf, tar tzf и tar xzf.


Короткая памятка

Задача Команда
Все .log рядом ls *.log
Все .txt рекурсивно find . -type f -name "*.txt"
Создать .tar.gz tar czf backup.tar.gz dir/
Посмотреть .tar.gz tar tzf backup.tar.gz
Распаковать .tar.gz tar xzf backup.tar.gz
Распаковать в директорию tar xzf backup.tar.gz -C /tmp/out
Сжать один файл gzip file.txt
Распаковать .gz gunzip file.txt.gz

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

Материал изучен?

Войдите, чтобы сохранить прогресс и перейти к практической лаборатории.

Войти и продолжить