creator cover Хелкод Скрипты и автоматизация
Хелкод Скрипты и автоматизация

Хелкод Скрипты и автоматизация 

Linux, DevOps, автоматизация

1subscriber

20posts

goals1
$0 of $69 raised
Аренда серверов для экспериментов, домены, платные инструменты. Чем мощнее железо - тем интереснее эксперименты)

About

Я веду канал @helcode - пишу про Linux, автоматизацию и всё,
с чем сталкивается инженер в реальной работе.
Что тут есть:
• Разборы инцидентов - как понять, что сломалось и как чинить
• Автоматизация - скрипты, systemd, CI/CD
• Инструменты - утилиты, которые экономят часы (вроде script)
• Туториалы - короткие и по делу
Посты выходят в Telegram @helcode. Сюда всё дублируется бесплатно -
для тех, кто хочет читать в ленте Boosty или ищет архив.
Подписки на Boosty - это способ сказать "спасибо" за работу над каналом.
Сейчас весь контент бесплатный. 
ncdu - визуальный анализ того, куда делось место

Ситуация: сервер ругается, что диск заполнен на 95%. Вы запускаете df -h, видите, что корень почти полный. Дальше начинаются танцы с du -sh */ - приходится долбиться в каждую папку, спускаться глубже, терять нить, забываать, где были.

ncdu (NCurses Disk Usage) делает то же самое, но с интерактивным интерфейсом, где можно ходить стрелками и сразу видеть всё дерево папок.

Как это работает:

Запускаем ncdu / - утилита сканирует директорию (от 10 секунд до пары минут, в зависимости от объёма) и показывает список папок и файлов, отсортированный по размеру.

Навигация внутри ncdu:
- Стрелки вверх/вниз - перемещение по списку
- Enter - зайти внутрь папки
- Стрелка влево - вернуться назад
- d - удалить выбранный файл/папку (с подтверждением)
- n - сортировка по имени (по умолчанию — по размеру)
- q - выход

Вариант 1 (Быстрый анализ конкретной папки):
ncdu /var
# Тут же видно, что /var/log весит 40 гигабайт


Вариант 2 (Сканирование в фоне с сохранением результата):
# Сохранить результат сканирования
ncdu -o /tmp/disk_usage.json /home

# Потом посмотреть без повторного сканирования
ncdu -f /tmp/disk_usage.json


Вариант 3 (Исключить определённые папки):
# Не сканировать монтирования и временные папки
ncdu --exclude /mnt --exclude /tmp /


Из личной практики:


Диск забился на сервере с сайтами. df -h показал, что проблема в /var. Запустил ncdu /var - увидел, что /var/log/nginx весит 30 гигабайт. Зашёл туда стрелкой, увидел, что один лог-файл раздулся до нечеловеческих размеров. Нажал d, подтвердил удаление - место освободилось за 30 секунд. Без ncdu я бы тыкался руками ещё полчаса.

Почему лучше, чем `du`: интерактивность, наглядность, возможность удалять прямо из интерфейса. Не нужно запоминать путь, чтобы потом писать rm -rf.

P.S. На больших дисках (несколько терабайт) первое сканирование может занять несколько минут. Запускайте через screen или tmux, чтобы не оборвалось.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
strace - смотрим, что процесс делает на самом деле

Бывает, процесс висит, жрёт CPU, но не падает. Логи молчат. Что делать? Танцы с бубном? Нет. Есть strace - утилита, которая показывает все системные вызовы процесса.

В Linux любая программа постоянно общается с ядром: читает файлы, пишет в сокеты, выделяет память. strace перехватывает этот диалог и показывает его вам.

Вариант 1 (Прицепиться к работающему процессу): процесс завис, но не умирает.
# Прицепиться к PID 1234
strace -p 1234

# Вывод:
# read(3, 0x7f8a2c000000, 4096) = -1 ETIMEDOUT (Connection timed out)
# Наглядно: процесс ждёт ответа от какого-то файлового дескриптора 3


Вариант 2 (Запустить программу под strace): нужно понять, почему падает при запуске.
# Запускаем и смотрим
strace ./my_binary

# Ищем строки с -1 (ошибка)
strace ./my_binary 2>&1 | grep -1


Вариант 3 (Фильтрация по конкретным вызовам): шума много, нужно только чтение файлов.
# Только open, read, write, close
strace -e trace=open,read,write,close ./my_binary

# Только сеть
strace -e trace=network ./my_binary


Вариант 4 (Сохранить вывод в файл): процесс падает редко, нужно записать всё.
strace -o /tmp/strace.log ./my_binary

Вариант 5 (Замерить время каждого вызова): где программа тормозит?
# -T показывает время выполнения каждого вызова
strace -T -e trace=read ./my_binary

# -c — сводная статистика в конце
strace -c ./my_binary


Когда strace бесполезен:
- Процесс тормозит, но не из-за системных вызовов (например, алгоритм O(n²))
- Проблема в самом ядре (туда уже нужен perf или trace-cmd)
- Программа работает с графикой/звуком через прямые вызовы драйверов

P.S. strace может влиять на производительность процесса в 10-100 раз. На проде прицепляйтесь аккуратно и ненадолго.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
lsof - кто держит порт и открыл тот файл

Ситуация: пытаетесь запустить сервер, а он падает с "Address already in use". Порт занят, но кем? Или пытаетесь удалить файл, а система пишет "file is in use". Кто его держит?

lsof (List Open Files) отвечает на оба вопроса. В Linux «всё есть файл» - сетевые сокеты, пайпы, устройства, обычные файлы. lsof показывает, какие процессы какие «файлы» открыли.

Вариант 1 (Кто занял порт): классический кейс с запуском сервера.
# Кто слушает 3000 порт?
lsof -i :3000

# Вывод: COMMAND PID USER FD NAME
# node 1234 user 23u IPv4 TCP *:3000 (LISTEN)


Вариант 2 (Какой процесс держит файл): не даёт удалить папку или файл.
# Кто использует файл лога?
lsof /var/log/app.log

# Кто работает в папке /home/user/project?
lsof +D /home/user/project


Вариант 3 (Все открытые файлы процесса): подозреваете конкретный процесс - смотрите, что он делает.
# Все файлы, открытые процессом с PID 1234
lsof -p 1234

# Сеть, которую использует процесс
lsof -p 1234 -i


Вариант 4 (Кто использует удалённый файл): монтирование не отдаёт, а кто мешает?
# Процессы, использующие файлы на смонтированном диске
lsof /mnt/usb

# Обычно это оболочка, которая "стоит" в папке на этом диске


lsof нужен, когда обычные инструменты молчат. Команда не показывает ошибку, но что-то мешает. lsof показывает «что именно» и «кто».

Альтернатива:
# Когда точно знаем, что ищем сетевой порт. Быстрее и чаще установлена по умолчанию.
ss -tlnp | grep 3000


lsof выручает, когда:
1. Нужно посмотреть не только TCP, но и UDP
2. Проблема не с портом, а с файлом или папкой
3. Хотите увидеть все соединения процесса целиком

P.S. Самый частый сценарий: lsof -i :8080 - видим PID - kill -9 PID. Всё, порт свободен.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode

grep: неочевидные возможности для глубокого анализа данных

grep - утилита, которую многие считают изученной до конца. Базовый синтаксис известен всем: grep "pattern" file. Однако в арсенале инструмента существует ряд возможностей, превращающих его из простого поисковика строк в полноценный анализатор логов, дампов и структурированных данных.
Расширенные сценарии использования:
➤ Поиск по временному диапазону
Логи типовых приложений содержат временные метки. Извлечение фрагмента между двумя отметками времени - типовая задача при анализе инцидентов.
Базовый подход - использование регулярного выражения, соответствующего временному интервалу. Более гибкий метод - комбинация -B (before) и -A (after), позволяющая захватить контекст вокруг целевой метки. Это особенно полезно, когда точное время события известно, а требуется увидеть предшествующие и последующие записи.
➤ Многострочные паттерны с поддержкой PCRE
Классический grep работает построчно. Для анализа стектрейсов или многострочных сообщений об ошибках этого недостаточно. Решение - активация Perl-совместимых регулярных выражений (-P) в связке с флагами -z (чтение файла как единой строки) и -о (вывод только совпавших фрагментов).
Режим -P открывает доступ к расширенным возможностям: нежадные квантификаторы, lookahead/lookbehind, поддержка \s, \d, \w и других шорткатов. Флаг -z заменяет символы перевода строки на нулевые байты, позволяя регулярному выражению охватывать несколько физических строк.
➤ Работа с бинарными файлами
При анализе дампов памяти, логов поврежденных приложений или бинарных протоколов grep по умолчанию отказывается обрабатывать файлы, содержащие нулевые байты. Флаг -a (или --text) принудительно интерпретирует бинарные файлы как текстовые.

socat: многоцелевой инструмент сетевой коммуникации

netcat (nc) - стандартный инструмент для работы с сетевыми соединениями, известный большинству системных администраторов и разработчиков. Однако его функциональность ограничена базовыми сценариями. Когда задача требует SSL/TLS, параллельной обработки нескольких соединений или привязки к конкретному сетевому интерфейсу, nc перестает быть достаточным решением.
socat (SOcket CAT) - это расширенная альтернатива, реализующая концепцию универсального сетевого соединителя. Он способен связывать практически любые типы адресов: файлы с сокетами, TCP-порты с SSL-туннелями, Unix-сокеты с UDP-эндпоинтами, а также выполнять произвольные команды при установлении соединения.
Архитектурная концепция
socat строит работу на абстракции "адрес" (address). Каждый адрес описывает один конец соединения - его тип, параметры и поведение. Инструмент устанавливает двунаправленную передачу данных между двумя адресами. Синтаксис, действительно, требует привыкания, но базовые паттерны осваиваются быстро и затем применяются по аналогии.
Типовые типы адресов:
  • TCP-LISTEN:<port> - прослушивание TCP-порта
  • TCP:<host>:<port> - подключение к удаленному TCP-порту
  • OPENSSL-LISTEN:<port> - прослушивание с SSL/TLS
  • UNIX-CONNECT:<path> - подключение к Unix-сокету
  • EXEC:<command> - выполнение команды
  • OPEN:<file> - работа с файлом
  • STDIO или - стандартный ввод-вывод

Практические применения

Проброс трафика и балансировка
Простейший сценарий - прием соединений на одном порту и перенаправление их на внутренний сервер. Опция fork критически важна: без нее socat обработает только одно соединение и завершится. С fork создается отдельный дочерний процесс для каждого входящего подключения, что позволяет обслуживать множество клиентов одновременно.
SSL/TLS-терминация
Для приложений, не поддерживающих HTTPS из коробки, socat может выступать как легковесный терминатор SSL. Указание сертификата, отключение проверки (для тестовых сред) и проброс на внутренний HTTP-порт создают полноценное защищенное соединение без развертывания полноценного веб-сервера.

fd: человеческий интерфейс для поиска файлов

find - инструмент удобный, но его синтаксис остается одной из главных проблем в повседневной работе. Каждый раз, когда требуется найти что-то сложнее базового find . -name "*.py", приходится обращаться к документации. Это когнитивная нагрузка, которая отвлекает от решения реальной задачи.
fd - альтернативная реализация, сохраняющая всю функциональность find, но с синтаксисом, который не требует постоянного обращения к man-страницам.
Ключевые отличия от find
  • Интуитивный синтаксис - шаблон поиска передается как первый аргумент, без опций -name или -path. fd .py вместо find . -name "*.py".
  • Уважение .gitignore по умолчанию - fd не ищет в node_modules, .venv и других игнорируемых директориях, если явно не указано иное.
  • Цветной вывод - файлы и директории подсвечиваются разными цветами, символические ссылки имеют отдельное оформление.
  • Регулярные выражения по умолчанию - шаблон интерпретируется как регулярное выражение, что делает поиск более гибким без дополнительных флагов.
  • Параллельная обработка - поиск выполняется в нескольких потоках, что дает прирост производительности на больших файловых системах.
Практические сценарии:
➤ Поиск файлов по имени
Базовые операции интуитивно понятны: расширение файла указывается без маски, регистронезависимый поиск - через -i, множественные расширения - через несколько флагов -e. Цветной вывод сразу показывает тип каждого найденного элемента.
➤ Поиск с исключениями
Исключение директорий и файлов работает через --exclude. Поскольку .gitignore учитывается автоматически, дополнительных действий для исключения стандартных артефактов не требуется. Флаг --hidden включает поиск в скрытых директориях.
➤ Выполнение команд над найденным
Встроенный механизм -x позволяет выполнить произвольную команду для каждого найденного файла, подставляя путь через {}. Это избавляет от необходимости использовать xargs и заниматься экранированием имен с пробелами и спецсимволами.
Экосистемная интеграция
fd отлично интегрируется с другими современными инструментами командной строки. Пайплайн fd | fzf создает интерактивный интерфейс для выбора файлов из всего проекта. В сочетании с ripgrep (rg) формируется полный набор инструментов для навигации по кодовой базе.

ripgrep: поиск по коду на порядок быстрее

grep — инструмент классический, но на крупных проектах его производительность становится узким местом. Ожидание, пока найдутся все вхождения функции, — потерянное время, которое накапливается.
ripgrep (rg) решает эту проблему архитектурно: SIMD-инструкции, параллельные потоки и умные алгоритмы пропуска файлов. Результат — поиск по проекту с 10 тысяч файлов занимает доли секунды вместо 10-15 секунд.
Ключевые отличия от grep
• Уважение .gitignore — по умолчанию не лезет в node_modules, .venv, target и прочие артефакты. В классическом grep нужно явно исключать.
• Скорость — в 10-50 раз быстрее на больших кодовых базах. Тесты на ядре Linux: grep — 15-20 секунд, rg — 0.4 секунды.
• Читаемый вывод — подсветка синтаксиса, номера строк, контекст, группировка совпадений по файлам.
• Кроссплатформенность — одинаково работает на Linux, macOS, Windows.
Сценарии использования
Поиск по коду — основная задача. Находит все вызовы функции, все использования типа или строки. Фильтрация по языку (Python, Rust, Go, JavaScript) и исключение тестовых директорий — встроенные возможности.
Анализ логов — с контекстом до и после найденной строки, с подсветкой разных элементов разными цветами. Позволяет быстро локализовать проблему.
Массовая замена — сначала получить список файлов под замену (--files-with-matches), верифицировать, затем выполнить замену через sed или другой инструмент. Риск контролируется, артефакты предсказуемы.

fzf: интерактивный поиск как стандарт терминальной работы

В повседневной работе с терминалом мы постоянно решаем задачу выбора: найти нужный файл среди тысяч, извлечь команду из глубины истории, идентифицировать процесс для завершения. Традиционные инструменты вроде grep решают задачу поиска, но не выбора. fzf заполняет этот пробел, превращая поток строк в интерактивный интерфейс с нечетким сопоставлением.
Утилита следует философии Unix: принимает на вход произвольный список строк, предоставляет интерактивный интерфейс для фильтрации и выбора, возвращает выбранное в stdout. Это позволяет встраивать интерактивность в существующие пайплайны без изменения привычных рабочих процессов.
Архитектура и принцип работы
fzf работает как фильтр, располагающийся в конвейере между генерацией данных и их потреблением. Ключевая особенность — алгоритм нечеткого поиска, который позволяет находить соответствия даже при неточном вводе. Это принципиально отличается от точного сопоставления, предлагаемого стандартными средствами.
Базовый синтаксис: генератор_данных | fzf [опции] | обработчик_выбора
После выбора элемент отправляется в stdout, где его можно передать следующему инструменту.
Практические применения
Вариант 1. Навигация по истории команд
Стандартный Ctrl+R в bash и zsh предоставляет линейный поиск по истории. Замена его на fzf превращает навигацию в интерактивный процесс с визуальным отображением всех совпадений.
ERR в bash: надежная обработка ошибок за пределами set -e
Level required:
Читатель

Как перестать чинить продакшен после каждого pip install и начать жить спокойно

Знаете этот момент: выкатываете обновление, а приложение падает с загадочной ошибкой. Начинаете копать и выясняете, что библиотека, которая работала вчера, сегодня обновила мажорную версию и сломала обратную совместимость. Классика.
Я через это проходил не раз. Особенно "весело" было в проекте, где зависимости управлялись через pip freeze > requirements.txt после каждого обновления. Что в итоге попадало в репозиторий — загадка. А когда приходилось откатывать версии вручную, потому что "у меня локально всё работает" — это отдельный квест.
Выход есть. И он называется правильное управление зависимостями. 
Почему pip freeze — это зло
На первый взгляд всё логично: заморозили текущие версии, закоммитили, всё стабильно. Но проблема в том, что в requirements.txt оказываются ВСЕ установленные пакеты — и те, что вы выбрали явно, и те, что подтянулись как зависимости. В итоге:
  • Непонятно, какие библиотеки реально нужны проекту
  • Обновление одного пакета тянет кучу транзитивных, которые тоже меняются
  • При попытке обновить конкретную библиотеку рискуете сломать всё остальное
Современные инструменты решают эту проблему, разделяя "что мы хотим" и "что у нас есть".
Покажу два подхода, которые использую в зависимости от проекта.
Вариант 1. Poetry (мой фаворит)
Subscription levels2

Читатель

$0.69 per month
Уведомления о новых материалах
Спасибо, что вы со мной!

Поддержка

$3.5 per month
Всё из первого тарифа
Понимание, что вы помогаете каналу развиваться
Go up