Helcode | Хелкод | Скрипты и автоматизация
992 subscribers
52 photos
34 links
☎️ Контакты для связи: @helcodeadm
Download Telegram
Скрипты на bash и их предсказуемость

Поймал себя на мысли, что многие пишут bash-скрипты как придётся. Запустили, оно вроде работает, и ладно. А потом скрипт падает в три часа ночи, потому что переменная оказалась пустой или в названии файла попался пробел.

Есть вещи, которые я всегда добавляю в начало любых скриптов:

#!/bin/bash
set -euo pipefail


➤ Разбор полётов:
- -e — скрипт умирает при первой же ошибке. Без этого флага он продолжит выполнение, даже если команда упала, и вы можете получить кашу.
- -u — если переменная не объявлена, скрипт сразу падает. Без этого флага пустая переменная превратится в пустую строку и может натворить дел (например, rm -rf $UNDEFINED удалит всё, потому что команда превратится в rm -rf).
- -o pipefail — если в пайпе что-то упало, весь пайп считается упавшим. Без этого флага false | true вернёт успех.

Проверка аргументов. Если скрипт требует аргументы, проверяйте их сразу.

if [ -z "${1:-}" ]; then
echo "Ошибка: не указан конфигурационный файл"
exit 1
fi


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

# Плохо
rm -rf $SOME_DIR

# Хорошо
rm -rf "$SOME_DIR"


Проверка на существование. Если скрипт работает с файлами, проверяйте, что они есть.

if [ ! -f "$CONFIG_FILE" ]; then
echo "Файл конфигурации не найден: $CONFIG_FILE"
exit 1
fi


Логирование. Пишите в stdout, что происходит. Это потом спасёт при разборе инцидентов.

echo "[$(date +'%Y-%m-%d %H:%M:%S')] Начинаю бэкап базы данных"


Я иногда смотрю на чужие скрипты и вижу там отсутствие этих простых вещей. В итоге скрипт работает на машине автора, потому что там есть нужные файлы и переменные, но падает на чистой системе. А виноват потом "кривой линух".

У вас были случаи, когда bash-скрипт падал из-за неожиданного пробела в имени файла или незаданной переменной?

🌐 @helcode
🔥9👍32🙏2
Про автоматизацию обновления сертификатов

Каждый, кто админит свои сервера, через это проходил. Просыпаешься утром, а сайт не открывается. Лезешь в логи, а там "SSL certificate expired". Руки чешутся, кофе стынет, сертификат протух ещё неделю назад.

Почему это вообще происходит. Let's Encrypt даёт сертификаты на 90 дней. Это не их прихоть, а стандарт индустрии - короткие сертификаты безопаснее. Но человеческая память короче 90 дней, и ручное обновление рано или поздно проспишь.

➤ 1. Ставим certbot. Он умеет не только получать сертификаты, но и продлевать их.
apt-get install certbot python3-certbot-nginx


➤ 2. Разово получаем сертификат.
certbot --nginx -d example.com -d www.example.com


➤ 3. Настраиваем автоматическое продление. Certbot создаёт systemd-таймер сам при установке. Проверить можно так:
systemctl status certbot.timer
systemctl list-timers | grep certbot


Таймер запускается два раза в день и проверяет, не пора ли обновить сертификаты. Если до истечения осталось меньше 30 дней - обновляет.

➤ 4. Добавляем хуки на перезагрузку. После обновления nginx нужно перезагрузить, чтобы он подхватил новый сертификат.
certbot renew --renew-hook "systemctl reload nginx"


➤ 5. Проверяем, что всё работает.
certbot renew --dry-run


Если вдруг certbot не вариант. Бывает, что сервер в закрытом контуре или используются внутренние CA. Тогда пишется простой скрипт в cron:

#!/bin/bash
# renew-internal-cert.sh

CERT_PATH="/etc/ssl/certs/myapp.crt"
EXPIRY_DAYS=$(openssl x509 -in "$CERT_PATH" -noout -enddate | cut -d= -f2 | xargs -I{} date -d "{}" +%s)
CURRENT=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_DAYS - CURRENT) / 86400 ))

if [ $DAYS_LEFT -lt 7 ]; then
echo "Сертификат скоро истекает ($DAYS_LEFT дней). Запускаю обновление..."
/usr/local/bin/update-internal-cert.sh
systemctl reload nginx
fi


В cron добавляется еженедельный запуск:
0 2 * * 1 /root/renew-internal-cert.sh


Важный момент. Автоматика автоматикой, но я всё равно добавляю мониторинг на дату истечения. Например, в Prometheus можно экспортировать метрику с днями до протухания и настроить алерт, если осталось меньше недели. Тогда даже если автоматика почему-то не сработала, будет время вмешаться вручную.

У кого как организовано обновление сертификатов? Доверяете автоматике или ходите раз в три месяца ручками продлевать?

🌐 @helcode
4👍3🔥1
Коллеги, рад всех приветствовать! Мы закончили миграцию: теперь нас можно читать не только в Телеграм!

Недавно я запускал голосование с вопросом: куда мигрируем на случай блокировки Телеграм? Вы ответили - и довольно однозначно. Спасибо всем, кто участвовал в опросе и оставлял комментарии.

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

Что имеем на выходе:

Основной канал как был в Телеграм, так и остается. Сюда я буду писать в первую очередь, здесь же будет основное обсуждение. Никаких "уходим навсегда" не планируется. Также, был переработан формат постов для адекватного репоста в иные соц. сети, весь .md формат (код) уходит в изображение. В ближайшее время мы с ним "познакомимся".

Но теперь у @helcode есть официальные зеркала на двух дополнительных площадках:

VK - для тех, кто привык читать ленту в соцсети и не хочет ставить лишние мессенджеры. Туда уходят все посты синхронно с Телеграм. Минус - в комментарии захожу реже, но читаю.

Boosty - для любителей блог-формата. Там же будет постепенно появляться расширенная версия некоторых материалов, если тема глубокая и не влезает в короткий пост. Об этом буду обязательно оповещать.

Статический сайт пока отложил. Идея хорошая, но требует времени на поддержку, которого и так в обрез. Возможно, вернусь к ней, когда накопится критическая масса контента, которую неудобно искать в соцсетях.

Резюмирую. Канал жив, контент выходит по плану, темы по автоматизации, Linux и утилитам никуда не делись. Если завтра Телеграм вдруг станет совсем недоступен - вы знаете, где искать. Все "перекрестные" ссылки будут под каждым постом!

🌐 @helcode
👍13👌41🔥1
Коллеги, всех приветствую!

Давно хотел показать что-то действительно полезное и при этом созданное внутри нашего сообщества. Знакомьтесь: DevToolbox Cheats - проект подписчика @boomlavka.

Для тех, кто, как и я, работает в Linux и постоянно ловит себя на мысли: "А какой там флаг у tar...?", "Как правильно смонтировать диск...?", "А как сбросить настройку iptables...?".

Что сделал автор? Он взял и упаковал более 100 готовых шпаргалок (Git, Bash, Docker, RegEx, Ansible и ещё много чего) в удобный интерфейс, который встраивается прямо в панель вашего рабочего стола.

Чем проект цепляет лично меня:
1. Универсальность: неважно, сидите вы в KDE, GNOME, XFCE или даже в голом i3 - утилита сама подстроится и будет выглядеть как родная.
2. Скорость: кэширование отрабатывает так, что список команд появляется быстрее, чем открывается браузер.
3. Копирование в один клик: нашёл команду - ткнул - она уже в буфере. Минимум телодвижений.
4. Умное редактирование: если встроенных шпаргалок вдруг покажется мало, автор продумал сценарий на любой случай. Можно открыть конфиг в любимом редакторе (VS Code, Geany и др.) - скрипт сам определит, что у вас стоит. Если редактор не найден или вы работаете в minimal окружении - файл откроется прямо во всплывающем окошке zenity.

Мы часто обсуждаем автоматизацию на уровне систем и скриптов, но автоматизация личного рабочего процесса - это то, что экономит часы каждую неделю. DevToolbox Cheats - именно про это. Не надо гуглить, не надо лезть в заметки. Просто кликнул на иконку и продолжил работу.

ВАЖНО:

Я знаю, что @boomlavka продолжает развивать проект, и ему, как любому разработчику, важна обратная связь. Если вы покопаетесь в репозитории и найдёте баг, или наоборот - придумаете, как улучшить - не стесняйтесь писать автору или создавать issue на GitHub. Сообщество сильное только тогда, когда Мы помогаем друг другу становиться лучше.

👉 Ссылка на [GitHub](https://github.com/dominatos/devtoolbox-cheats)
Буду благодарен, если поставите звёздочку тем, кто зайдёт. Автору будет приятно, а каналу - почётно, что наши коллеги делают полезные инструменты.

P.S. Если у кого-то тоже есть свои проекты или полезные наработки - смело пишите в личку (@helcodeadm). Покажем, обсудим, поддержим.

🌐 @helcode
6🤔3
Helcode | Хелкод | Скрипты и автоматизация pinned «Коллеги, рад всех приветствовать! Мы закончили миграцию: теперь нас можно читать не только в Телеграм! Недавно я запускал голосование с вопросом: куда мигрируем на случай блокировки Телеграм? Вы ответили - и довольно однозначно. Спасибо всем, кто участвовал…»
Ansible: миф об идемпотентности и как не прострелить себе ногу

Ansible позиционируется как идемпотентный инструмент: можно запустить плейбук сто раз, и система будет в одном и том же состоянии. В теории - красиво, на практике - не всегда. Главная боль возникает, когда вы начинаете писать собственные сценарии с модулями command или shell. Они по умолчанию не идемпотентны. Запустите их дважды - они выполнятся дважды.

Чтобы побороть это, используют параметры creates и removes (проверка наличия файла-маркера), changed_when и failed_when (тонкая настройка условий изменения и ошибки). Но это всё костыли. Если вы ловите себя на том, что часто используете shell вместо специализированных модулей (copy, template, file, lineinfile, package), значит, вы пишете не декларативный код, а процедурный скрипт на bash внутри Ansible.

Стоит помнить: Ansible хорош ровно настолько, насколько хорошо вы используете его модули. Если задача сложная и требует логики, может быть, проще написать скрипт на Python и вызвать его через модуль script, сохранив идемпотентность на уровне внешнего скрипта.

🌐 @helcode
👍9🤔32
Доброго времени суток! Попробуем истории из личной практики?)

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

# Увеличиваем счетчик на 1
i = i + 1;
# Проверяем, не больше ли 10
if (i > 10) {
# Если больше, сбрасываем
i = 0;
}

Сначала это было действительно забавно. Спустя время мы пытались объяснить, что код должен быть "самодокументируемым" (поясню для тех, кто с термином не знаком. Это некий стиль написания кода, при котором он пишется настолько ясно, чисто и понятно, что не требует внешних комментариев для понимания его логики работы).

Через примерно год его код превратился в простыню, где читать комментарии было дольше, чем разбираться в логике. А когда он уволился и нужно было править его модуль, мы осознали весь звиздец ситуации: комментарии были на русском, переменные на английском, а логика - на каком-то своём, крайне непонятном.

При этом, половина комментариев уже давно не соответствовала реальности, потому что код меняли, а комментарии не трогали. Зачем, верно?)

На самом деле, даже рад случившемуся, много полезного усвоил. После той ситуации и отношение к коду/комментариям поменялось. Стараюсь писать максимально понятно.

🌐 @helcode
😁51👎1🌚1
Небольшая история про оптимизацию

Была у нас микросервисная архитектура. Красивая, как в учебниках. Каждый сервис делал что-то одно и делал хорошо. Только вот беда - их было 47 штук.

Один сервис отвечал за генерацию PDF, второй за отправку писем, третий за превьюшки картинок, четвёртый за сборку всего этого в отчёты... Ну, вы поняли.

Прилетает задача: ускорить генерацию отчёта. Менеджеры жалуются - целых 3 секунды приходится ждать, "пока там крутится".

Полез оптимизировать. Лимиты поднял, запросы распараллелил, кэширование добавил. В общем, добился ускорения до 1.5 секунд. Пошёл к руководству, отчитываться.

Получил вопрос: "А логи посмотрел?". Вернулся, пошёл смотреть логи... 0.5 секунды из 1.5 - сбор метрик для нашего же мониторинга, ещё 0.5 - запись в лог...

Выключил метрики на тестовом стенде, отчёт прилетел за 0.3 секунды. Теперь стараюсь придерживаться правила: прежде чем оптимизировать - посмотреть, сколько времени жрёт наблюдаемость.

P.S. Если вдруг заходит подобный формат - пишите, буду периодически рассказывать что-то из личной практики)

🌐 @helcode
👍272😁2
Недавно в комментариях упоминал сайт SadServers. Обещал рассказать - выполняю.

Фактически, это некий тренажёр для получения практических навыков. Вкратце: вам дают сервер, который "сломан" определённым образом. Нам дают описание проблемы, время на выполнение и задачу: пофиксить. После изучения задачи тыкаем "run" и получаем доступ по SSH к проблемной машине прямо в браузере. Интересно, не так ли?)

Сценариев там под сотню (если не больше), разбиты по категориям: Linux/Bsh, Web Servers, Databases, Data Processing, Docker, Kubernetes, Tooling, Hacking, Languages. Описал буквально всё. Также, сценарии разбиты на категории по сложности:

- Easy - для разминки. Типа "почему не стартует SSH?" или "кто жрёт память". Проходятся за 10-15 минут, если руками всё умеешь.
- Medium - тут уже интереснее. Может быть проблема с неправильными правами, кривым конфигом или процессом, который падает при старте, но оставляет мутные логи.
- Hard - для тех, кто хочет поплакать. Например: "PostgreSQL не отвечает, но в логах тишина, и всё настроено правильно. Спойлер: не правильно".

Большая часть доступна бесплатно, но присутствуют и сценарии по подписке. Также, важно упомянуть:

Сайт стал работать значительно хуже, присутствует долгая загрузка и тормоза. У меня заведены 2 провайдера, на одном из них тормоза практических отсутствуют. Возможно, у вас ситуация будет отличаться. В любом случае советую использовать VPN.


Лично я прорешал штук 15. Задачи интересные, задумка - шикарная. Советую всем, от начинающих до бывалых, практические скиллы прокачать помогает.

Ссылку прилагаю: https://sadservers.com/scenarios

🌐 @helcode
👍142🔥1
Я храню список своих факапов...

У меня есть файл. Называется "failures .md". Там лежат все мои ошибки за последние годы.

Не чтобы себя мучить, а чтобы не наступать на те же грабли. Проблемы часто повторяются, решение забывается. Следовательно, повторяются и ошибки...

Когда случайно удалил базу - записал, как это произошло и что делать, если повторится.
Когда уронил прод кривым деплоем - записал, почему так вышло и как проверять перед мержем.
Когда три часа искал баг, который оказался отсутствующей запятой - записал, в каких местах такие запятые любят прятаться.

Иногда я перечитываю этот файл перед сложными задачами. Знаете, как некую мантру: "Проверь права доступа, не деплой в пятницу, сделай бекап".

Некоторые коллеги говорят, что это паранойя. Но когда в очередной раз кто-то наступает на те же грабли, я открываю свой файл и скидываю ссылку: "Почитай, у меня уже было".

Стыдно за ошибки? Сначала было. Потом понял, что ошибаются все. Умные просто стараются не повторять.

А вы ведёте дневник ошибок или полагаетесь на память?

🌐 @helcode
👍161🔥1
Три вещи, которые я проверяю, когда сервер тормозит

Был у меня период, когда любое падение производительности я встречал с одним рефлексом - лезть в код. Казалось, что если сервер еле дышит, значит, я где-то накосячил с алгоритмами.

Переписывал запросы, оптимизировал функции, добавлял кэши там, где они не нужны. А потом выяснялось, что проблема была вообще не в коде. Просто кто-то запустил бекап в "час пик" или диск забился логами.

Со временем выработался некий чек-лист. Три точки, которые я проверяю в первую очередь, прежде чем трогать код.

Первое - память.

Самый частый сценарий: какой-то процесс утёк и сожрал всю оперативку. Система начинает свопиться - сбрасывать данные на диск. А диск даже самый быстрый - это не оперативная память. Всё встаёт колом.

Смотрю free -h. Если used почти равно total, а swap использован - значит, память под завязку. Дальше htop показывает, кто жрёт. Часто помогает простой перезапуск проблемного процесса, чтобы выиграть время на поиск настоящей причины.

Второе - диск.

Бывает, памяти дофига, процессор простаивает, а сервер еле шевелится. Это классический I/O wait - процессы висят в очереди на чтение или запись.

Смотрю iotop. Если вижу, что какой-то процесс постоянно долбит диск на максимальной скорости - вот он, виновник. Чаще всего это:

- Забытый бекап, который решил запуститься в обед
- Логи, которые пишутся в один файл без ротации годами
- База, которая выполняет тяжёлый запрос и не влезает в память

Иногда достаточно просто прибить процесс или понизить ему приоритет, чтобы основной сервис вздохнул свободно.

Третье - сеть.

Сервер в порядке, а пользователи всё равно жалуются на тормоза. Значит, проблема может быть на пути к нему.

Смотрю mtr до сервера из внешней точки. Если потери начинаются на конкретном узле до моего железа - вопрос к провайдеру. Если на самом сервере - проверяю загрузку сетевого интерфейса через iftop.

Что дальше

Если с памятью, диском и сетью всё в порядке - тогда уже лезу в код, логи, базу. Но в восьми случаях из десяти проблема находится на этом первом этапе. И решается не оптимизацией запросов, а убийством кривого процесса или разговором с коллегой, который запустил бекап не вовремя.

А вы с чего начинаете диагностику?

🌐 @helcode
👍10🔥72💯1
Makefile: единый интерфейс для команд проекта

Каждый проект обрастает набором команд для установки, тестирования и запуска. Хранить их в памяти или в wiki - неэффективно. Makefile позволяет собрать все команды в одном месте и сделать их доступными через короткие алиасы.

Новый разработчик в проекте выполняет make help и видит все доступные операции.

* Вариант 1 (Python-проект): сокращение часто используемых команд.
.PHONY: install run test clean

install:
pip install -r requirements.txt

run:
python app.py

test:
pytest tests/

clean:
find . -type d -name "__pycache__" -exec rm -rf {} +


* Вариант 2 (Node.js + Docker): объединение нескольких шагов в один.
.PHONY: docker-build docker-run logs

docker-build:
docker build -t myapp .

docker-run: docker-build
docker run -p 3000:3000 myapp

logs:
docker logs myapp-container


Makefile работает как документация. Если команда сложная, ее не нужно искать в истории терминала - она записана и всегда под рукой.

Используете ли вы Makefile в проектах, не связанных с C/C++?

P.S. Make умеет отслеживать изменения файлов и перезапускать только те команды, которые действительно нужны.

Важно! На Boosty расписал пост подробно. Телеграм имеет определенные ограничения на длину.

Я в Telegram - t.me/helcode
Я в VK - vk.com/helcode
Я на Boosty - boosty.to/helcode
👍61
Pre-commit хуки: автоматические проверки до коммита

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

Pre-commit хуки запускают проверки автоматически и не дают создать коммит, если код не соответствует стандартам.

Вариант 1 (Базовый конфиг для Python): автоматическое приведение кода к единому стилю.
# .pre-commit-config.yaml
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: trailing-whitespace # Удаляет пробелы в концах строк
- id: end-of-file-fixer # Добавляет перевод строки в конце файла
- repo: https://github.com/psf/black
rev: 23.1.0
hooks:
- id: black # Форматирует код


Вариант 2 (Проверка секретов): блокировка коммита с потенциальными ключами доступа.
  - repo: https://github.com/Yelp/detect-secrets
rev: v1.4.0
hooks:
- id: detect-secrets


После настройки хуков код в репозитории всегда проходит базовые проверки. Это снижает нагрузку на ревьюверов.

Есть ли у вас в проекте автоматические проверки перед коммитом?

P.S. Конфигурация pre-commit хранится в репозитории, поэтому все разработчики в команде используют одинаковые проверки.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
5👍2🔥1
Bash-скрипты для регулярных операций

Повторяющиеся действия, которые выполняются чаще одного раза, стоит автоматизировать. Это касается бэкапов, ротации логов, синхронизации данных. Bash-скрипты - самый доступный способ такой автоматизации.

Скрипт можно запустить вручную или по расписанию через cron. Результат всегда предсказуем.

Вариант 1 (Бэкап БД с ротацией):
#!/bin/bash
BACKUP_DIR="/backups/postgres"
DB_NAME="myapp"
DATE=$(date +%Y%m%d_%H%M%S)

# Создание дампа
pg_dump $DB_NAME > $BACKUP_DIR/db_backup_$DATE.sql

# Сжатие
gzip $BACKUP_DIR/db_backup_$DATE.sql

# Удаление бэкапов старше 7 дней
find $BACKUP_DIR -name "db_backup_*.sql.gz" -mtime +7 -delete

echo "Backup completed: db_backup_$DATE.sql.gz"


Вариант 2 (Синхронизация с S3):
tar -czf logs_$(date +%Y%m%d).tar.gz /var/log/myapp && aws s3 cp logs_$(date +%Y%m%d).tar.gz s3://myapp-logs-bucket/ --storage-class STANDARD_IA

Скрипты в репозитории обеспечивают прозрачность процессов. Любой член команды может посмотреть, как именно выполняется бэкап или синхронизация.

Что в ваших проектах автоматизировано скриптами, а что до сих пор делается вручную?

P.S. Добавление в скрипты проверок кодов возврата (set -e) и логирования делает их пригодными для использования в промышленной среде.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍52🔥1
GitLab CI: автоматизация сборки и доставки

Ручной деплой на сервер требует запоминания последовательности команд и несет риск ошибки из-за человеческого фактора. CI/CD-пайплайны делают процесс воспроизводимым: одна и та же последовательность шагов выполняется каждый раз.

GitLab CI встроен в систему контроля версий, что позволяет привязать деплой к событиям в репозитории.

Вариант 1 (Тесты и деплой на staging):
# .gitlab-ci.yml
stages:
- test
- deploy

run_tests:
stage: test
script:
- npm install
- npm run test

deploy_staging:
stage: deploy
script:
- rsync -avz --delete ./ user@staging-server:/var/www/html/
only:
- develop


Вариант 2 (Ручной деплой на продакшн по тегу):
deploy_production:
stage: deploy
script:
- ansible-playbook -i prod.inventory deploy.yml
only:
- tags
when: manual


Пайплайн гарантирует, что код перед попаданием на продакшен проходит все необходимые проверки в одинаковом окружении.

Кто выполняет деплой в вашей команде - разработчик или CI-система?

P.S. В GitLab CI можно переиспользовать шаблоны через include, чтобы не дублировать код пайплайнов в разных проектах.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍2
Управление зависимостями Python: фиксация версий

Обновление пакетов в Python-проекте без системы управления зависимостями часто приводит к неожиданным поломкам. Пакет обновляется, тянет за собой другие версии библиотек, и приложение перестает работать.

Современные инструменты разделяют понятия "зависимости, которые нам нужны" и "конкретные версии, которые установлены".

* Вариант 1 (Poetry):
# Команды для работы с зависимостями
poetry add requests@latest # Добавление или обновление пакета
poetry update # Обновление всех пакетов в рамках ограничений
poetry export -f requirements.txt --output requirements.txt # Экспорт для Docker


* Вариант 2 (pip-tools): pазделение на прямые и транзитивные зависимости.
# update_deps.sh
pip-compile requirements.in # Генерация requirements.txt с фиксированными версиями
pip-sync requirements.txt # Приведение окружения к состоянию из requirements.txt


Фиксация версий через lock-файлы гарантирует, что у всех разработчиков и на сервере будет одинаковый набор библиотек.

Используете ли вы pip freeze или более продвинутые инструменты для управления зависимостями?

P.S. Файл с зафиксированными версиями (poetry.lock или requirements.txt) должен быть в репозитории, а файл с верхнеуровневыми зависимостями (pyproject.toml или requirements.in) - тем более.

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍2
Vagrant: изоляция через виртуальные машины

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

Vagrant позволяет поднимать виртуальные машины с заданными параметрами и автоматически их настраивать.

* Вариант 1 (Веб-сервер под Ubuntu):
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/focal64"
config.vm.network "private_network", ip: "192.168.56.10"
config.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
vb.cpus = 2
end
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y apache2
SHELL
end


* Вариант 2 (Кластер из двух машин): поднятие взаимодействующих серверов для тестирования распределенных приложений.

vagrant up создает чистую среду, vagrant destroy полностью ее удаляет. Это позволяет тестировать установку и настройку с нуля без захламления основной системы.

Для каких задач в вашей команде используют виртуальные машины вместо контейнеров?

*P.S. Vagrant работает поверх VirtualBox, VMware или гипервизоров облачных провайдеров, предоставляя единый интерфейс управления.*

🌐 @helcode
5👍4
ERR в bash: отлавливаем ошибки там, где set -e бессилен

Все знают про set -e, который прерывает скрипт при первой ошибке. Но у него есть особенности: он срабатывает не на все ошибки, и его поведение может меняться в зависимости от контекста. Например, ошибка в конвейере (`cmd1 | cmd2`) не остановит скрипт, если не включен set -o pipefail. Или ошибка в условии if — там set -e вообще игнорируется.

Но есть механизм, который дает полный контроль над обработкой ошибок — ловушка ERR. trap 'echo "Ошибка в строке $LINENO"' ERR сработает при любой ошибке выполнения команды, независимо от настроек set -e. Причем вы получите номер строки, где это случилось.

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

Важно помнить: ловушка ERR не ловит ошибки в функциях, если они вызываны в подшеллах. И если вы явно игнорируете ошибку через cmd || true, ERR тоже не сработает.

Как вы обрабатываете неожиданные ошибки в скриптах — надеетесь на set -e или пишете полноценные обработчики?

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
👍61🔥1
Midnight Commander - это та утилита, которая кажется бессмысленной, пока не появится задача на сервере, где нужно быстро перекинуть 50 файлов из одной папки в другую. cp -r с кучей флагов - это долго. А в mc это делается секунд за 10.

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

Запустили mc - две панели. Левая папка, правая папка. Стрелки - навигация. Tab - переключить панель. F5 - копировать, F6 - переместить, F7 - создать папку, F8 - удалить. Всё.

Где реально выручает

· Выборочное копирование. Нужно из 500 файлов перенести 20 конкретных? Отмечаем их пробелом, жмём F5 - готово.
· Редактирование на месте. Нажали F4 - открылся редактор с подсветкой. Поправили конфиг - Ctrl+S, F10 - вышел.
· Архивы. Нажали Enter на .tar.gz - внутри, как в обычной папке. Копируем файлы наружу, не распаковывая всё.

Скрытые плюсы

· Alt+O - открыть текущую папку на второй панели. Удобно, когда нужно скопировать файл в параллельную ветку.
· Внизу можно писать команды, не выходя из mc. Например, tar -czf backup.tar.gz * - и архив готов.
· Мышь работает, но лучше привыкнуть к клавишам.

Если вы помните все флаги rsync и find - mc не нужен. Если нет - ставится одной командой и экономит время каждый раз, когда нужно что-то переложить на сервере.

P.S. Прошу прощения за несколько уведомлений, Телеграм решил, что не будет планировать мой пост, а дропнет сразу…

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
🔥7👍51
fzf: поиск, который работает везде

Каждый день мы ищем: файлы в проекте, команды в истории, процессы для убийства. grep находит, но не выбирает. fzf добавляет интерактивный поиск с нечетким сопоставлением туда, где его раньше не было.

Утилита принимает список строк на вход, а на выходе отдаёт выбранную.

➤ Вариант 1 (Поиск по истории команд): привязка к Ctrl+R превращает поиск в истории из слепого перебора в интерактивную прогулку.
# Добавить в .bashrc или .zshrc
bind '"\C-r": "\C-e \C-u history | fzf --tac --no-sort | xargs -I {} echo {}"'

➤ Вариант 2 (Быстрый переход в папку): больше не нужно помнить, где лежит проект, запущенный месяц назад.
# Переход в любую папку в проектах
cd $(find ~/projects -type d 2>/dev/null | fzf)

# Или с предпросмотром содержимого
cd $(find ~/projects -type d | fzf --preview 'ls -la {}')

➤ Вариант 3 (Поиск и убийство процесса): нашел процесс глазами — убил, не выходя из поиска.
# Выбрали процесс — отправили SIGTERM
kill -15 $(ps aux | fzf | awk '{print $2}')

# С предпросмотром деталей процесса
kill -15 $(ps aux | fzf --preview 'echo {}' | awk '{print $2}')

fzf
работает как пайплайн: слева что угодно (файлы, процессы, строки), справа — действие над выбранным. Один раз настроив, вы получаете интерактивность там, где раньше был только слепой grep.

Используете ли вы интерактивный поиск в терминале или предпочитаете старый добрый Ctrl+R?

*P.S. В zsh можно настроить автодополнение команд через fzf — набираем kill **, нажимаем Tab, и выбираем процесс из списка.*

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode (тут выходит более подробный материал)
6🔥2👍1
ripgrep: grep, который не заставляет ждать

grep
хорош, но на больших проектах он тормозит. ripgrep (команда rg`) ищет в 10-20 раз быстрее, умеет игнорировать .gitignore` по умолчанию и выводит результат с контекстом.

Фраза «подожди, я сейчас найду где это используется» — это симптом, который лечится заменой инструмента.

➤ Вариант 1 (Поиск по коду проекта): находит все вызовы функции за доли секунды, даже в проекте с 10k файлов.
# Найти все вызовы calculate_price во всём проекте
rg "calculate_price"

# Только в Python-файлах, игнорируя тесты
rg -t py "calculate_price" -g "!tests/**"

# Найти TODO и показать имя файла и номер строки
rg -n "TODO"

➤ Вариант 2 (Поиск с контекстом и подсветкой): видно не только где, но и что было до и после.
# Показать 3 строки до и после найденного
rg -C 3 "error" logs/application.log

# Только имена файлов, где нашлось
rg -l "password" --hidden

# Подсветка совпадений разными цветами
rg --colors 'match:bg:yellow' "TODO"

➤ Вариант 3 (Замена во всех файлах): безопасная замена с предварительным просмотром.
# Сначала посмотреть, что попадёт под замену
rg "old_function" --files-with-matches

# Потом заменить с бекапом
rg "old_function" --files-with-matches | \
xargs sed -i.bak 's/old_function/new_function/g'

ripgrep
использует SIMD-инструкции и умные алгоритмы поиска. На проекте с 10k файлов он находит всё за секунду, пока grep ещё думает. И главное - он "уважает" .gitignore, поэтому случайно не залезет в node_modules.

Пробовали ли вы rg или остались верны классическому grep?

*P.S. rg отлично дружит с fzf: rg --no-heading "TODO" | fzf — интерактивный поиск по всем TODO в проекте.*

👉🏻 Я в Telegram - t.me/helcode
👉🏻 Я в VK - vk.com/helcode
👉🏻 Я на Boosty - boosty.to/helcode
🔥42👍1🤔1