Bash Days | Linux | DevOps
23.7K subscribers
225 photos
26 videos
776 links
Авторский блог от действующего девопса

Самобытно про разработку, devops, linux, скрипты, сисадминство, техдирство и за айтишную жизу.

Автор: Роман Шубин
Реклама: @maxgrue

MAX: https://max.ru/bashdays

Курс: @tormozilla_bot
Блог: https://bashdays.ru
Download Telegram
Всем привет. Вчера решал задачу фильтрации txt-файла и нашёл конструкцию на awk, от которой испытал эстетический оргазм. Решил с вами ею поделиться.

Итак, задача: есть _data.txt_ с данными и _filter.txt_ со списком фильтрации.

Строки data.txt обрабатываются, если есть совпадение в filter.txt. Это классическая задача фильтрации (например, обработка белых и чёрных списков).

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

👍 Итак, сама конструкция:


awk 'NR == FNR { filter[$0] = 1; next } $0 in filter { print $0, "in filter" }' filter.txt data.txt


Обратите внимание: здесь два блока обработки строк, каждый со своим условием

1. NR == FNR { filter[$0] = 1; next }
2. $0 in filter { print $0, "in filter" }

Обычно выполняются оба блока: сначала первый, потом второй, но здесь это не так. Первый блок только считывает данные filter.txt в массив filter.

Второй обрабатывает только те строки, которые есть в массиве.

NR — встроенная переменная, номер записи ДЛЯ ВСЕХ файлов.
FNR — аналогична предыдущей, но начинается с 1 для каждого нового файла.
filter[$0] = 1 — сохраняем всю строку первого файла как ключ массива.
next — сразу переходит к обработке следующей строки.

Таким образом, связка условия NR == FNR и next будет работать только для первого файла (filter.txt).

Для второго файла условие NR == FNR уже не соблюдается, поэтому первый блок не выполняется, а второй выполняется, если строка данных присутствует в массиве filter.

Ну и пример из реальной жизни — filter.txt:

RU
BY


data.txt

RU 127.0.0.1
BY 127.0.0.2
US 127.0.0.3
KZ 127.0.0.4


awk 'NR == FNR { filter[$1] = 1; next } $1 in filter { print $2, "in filter" }' filter.txt data.txt

127.0.0.1 in filter
127.0.0.2 in filter


Обратите внимание: на выходе только нужные строки и только нужный столбец. Как же это круто!

Маленькое ограничение: содержимое filter.txt, загруженное в массив filter, должно помещаться в оперативную память. Иначе система может начать активно использовать swap, а процесс — завершиться из-за нехватки памяти.

man awk
man comm
man join


Всем работы без багов.

© Tagd Tagd

🛠 #devops #bash #linux

💬 Bashdays 📲 MAX 🌐 LF 🔵 Blog
Please open Telegram to view this post
VIEW IN TELEGRAM
67
Я начал практиковать собесы с закрытыми глазами.

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

Но мы то знаем правду… 90% сидят на ИИшке и зачитывают ответы, это блядь просто смешно выглядит. Сначала кандидат выслушивает вопрос, потом 3 минуты начинает мычать вообще не по теме. А потом чудесным образом приходит в себя и начинает выдавать правильные ответы, что аж от языка отлетает.

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

Мир изменился, поэтому приходится придумывать новые фильтры. На любого хитрожопого, найдется более хитрожопый.

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

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

Смешно, но скоро так и будет — засунул себе поглубже и мозг наполняется нейросетевыми высерами.

Короче мозги не еби, будь честен, прозрачен, можешь припизднуть конечно, но всегда знай меру и балансируй по ситуации. Тыж головастый.

🛠 #workflow

💬 Bashdays 📲 MAX 🌐 LF 🔵 Blog
Please open Telegram to view this post
VIEW IN TELEGRAM
1123
This media is not supported in your browser
VIEW IN TELEGRAM
☁️☁️☁️☁️☁️☁️☁️

24 сентября Yandex Cloud проведёт Yandex Scale 2026 — флагманскую технологическую конференцию, посвящённую облачным технологиям, инфраструктуре и искусственному интеллекту.

🎨🎨🎨🎨🎨🎨🎨🎨🎨🎨
🎨🎨🎨🎨🎨🎨🎨🎨🎨🎨
🎨🎨🎨🎨🎨🎨🎨🎨🎨
В программе четыре продуктовых трека — AI, Data, Security и Hybrid Infrastructure & DevOps, — и отдельный углублённый технологический трек DeepTech, который пройдёт только онлайн.

В треке Hybrid Infrastructure & DevOps откроем программу рассказом про главные инфраструктурные анонсы и новинки 2026 года. На примере Stackland расскажем, как построить свою внутреннюю платформу по методологии Platform Engineering и ускорить time to market. Разберём, зачем бизнесу кластеры Yandex Managed Service for Kubernetes на тысячи нод — на реальном продакшн-кейсе Mindbox. Расскажем, как получить предсказуемую и безопасную ИИ‑разработку с ИИ‑командой на платформе SourceCraft и максимизировать возврат инвестиций от ИИ. Разберём возможности построения реальной гибридной инфраструктуры на базе единой технологической платформы и то, как полноценно объединить локальную и облачную среды, включая выделенные серверы BareMetal. И на примере крупного банка рассмотрим, как создать полноценный гибрид, соблюдая требования безопасности, регуляторов и бизнеса одновременно.

🎨🎨🎨🎨🎨🎨🎨🎨🎨🎨
🎨🎨🎨🎨🎨🎨🎨🎨🎨🎨
🎨🎨🎨🎨🎨🎨🎨🎨🎨
Отдельно пройдут воркшопы по Hybrid Infrastructure & DevOps. Смоделируем аварию на физическом сервере и проверим, как гибридная архитектура на облаке и BareMetal держит отказоустойчивость. Научим разворачивать корпоративную ИИ-систему с RAG-сценарием на Yandex BareMetal и Stackland — чтобы модель работала с внутренней документацией и базами знаний. Разберём, как эффективно делить GPU-ресурсы Yandex Managed Service for Kubernetes между параллельными задачами обучения моделей. И покажем, как команда ИИ-агентов SourceCraft проходит путь от бизнес-требований до безопасного релиза — с проверкой на уязвимости на каждом шаге.

🎨🎨🎨🎨🎨🎨🎨🎨🎨🎨
🎨🎨🎨🎨🎨🎨🎨🎨🎨🎨

На конференции будут не только треки — ещё демозоны, питчинг решений, IT-квест и мерч. Параллельно в онлайн-студии — розыгрыш призов и секретный гость.


Программа целиком — на сайте конференции, регистрация там же, а участие бесплатное!
Please open Telegram to view this post
VIEW IN TELEGRAM
8
Мёртвое ядро или мой новый проект DK.

Чё тянуть кота за яйца, интригу закину https://deadkernel.ru, полный анонс будет чуть позже…

Где-то там плачет грустный хуй сервер, а у нас всё по взрослому.

Для студентов Linux Factory бонусы, но они и так уже про них знают и активно используют.


Неси своё слово, делись с коллегами годнотой 😻
Please open Telegram to view this post
VIEW IN TELEGRAM
152
Forwarded from Selectel
💯 Команды для спасения вечера сисадмина. Часть 2

Какой день рождения Linux без серии консольных команд? Экономим часы рутины с подборкой от Романа Шубина, СТО и автора канала Bash Days.

Не забудьте поделиться находкой с коллегами!
77
Сисадмин может бесконечно смотреть на три вещи: логи, метрики и команду, которая почему-то ничего не вывела.

Чтобы смотреть пришлось недолго, я с ребятами из Selectel собрал ещё пять полезных команд. Готовые примеры и короткие объяснения — в посте выше 👆
37
Kuber Factory & Linux Factory

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

Механика конечно хитрая, тем кто уже состоит в Linux Factory, доступ к новому интенсиву открывается только после прохождения первых двух сезонов.

НО, если ты ебал и хочешь конкретно в Кубер Фектори, то можешь вписаться в него отдельно. Да, это выйдет дороже, но тебе не нужно будет делать 40 домашек. Компромисс хули.


Да еще параллельно стартовал 5й сезон, это приложение к первым двум сезонам, всё то, что мы пропустили, но заслуживает отдельного внимания.

А еще стартовал проект «Мёртвое ядро», с практическими задачами. На машинах полноценный линукс, без хуйни. Даже инстансы гитлаба настоящие поднимаются под задачки, можешь в морде мышкой тыкать. Перед собесами, само-то потыкать машинки и интересующие тебя темы. Кубера там кстати тоже дохера.

Ну и прицепом, я разработал учебную площадку, теперь никаких телеграмов, всё в вебе, все работает в РФ без кровавых прокладок. Сдаешь домашки, видишь свой статус, соревнуешься с другими ребятами, видишь свой прогресс.

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


- Вписаться в Linux Factory
-
Вписать в Kuber Factory

По всем вопросам, можешь писать сюда: @linuxfactorybot

И да, всех с 1м сентября, сил вам ребят и терпения!
Please open Telegram to view this post
VIEW IN TELEGRAM
77
Аренда выделенных серверов без вечной рутины с ними — бывает?

Обычно если хочешь отдельное «железо», то вместе с ним получаешь весь комплект: купить, настроить, обновлять, чинить, следить. Вроде бы логично: отдельное железо, свои ресурсы, никакого соседства с чужими нагрузками.При этом полностью уходить в публичное облако подходит не для всех сценариев.

Похоже, поэтому появляются промежуточные варианты. Yandex B2B Tech запустила Yandex BareMetal Extend — инфраструктура здесь физически отделена от публичного облака, но часть работы с ней уже берёт на себя провайдер.

Внутри можно выбрать виртуализацию, Kubernetes® или Stackland. Есть резервирование ресурсов и приватное соединение между выделенными серверами.

Функционал с виртуализацией сделали вместе с K2 Cloud, поддержку тоже организовали совместно.

Короче, идея простая: хочешь выделенное железо — пожалуйста. Хочешь при этом меньше заниматься инфраструктурной рутиной — тоже можно.
8
Я тут знатно дал ёба и приобрел это. Вот что случается с человеком, который всю жизнь пил пиво и потом перестал. Мало мне сломанных пальцев после знакомства в вимом.

Ладно, на самом деле не всё так хуёва… Это я снова себя успокаиваю…

Взял я эту клавиатуру в командировку, как единственную, даже не распаковывая, думаю — аааа, на месте разберусь, хули там, этож клавиатура, а не поиски клитора.

Ага, хуй там плавал. Я даже поверил в себя и не стал брать мышь.

На деле всё вышло довольно печально, этот пост я пишу десятый час, потому что мозг просто взрывается, мой KPI упал ниже плинтуса,

Условные рефлексы полностью отключились, мышечная память делает хуйню. Вот прям один в один опыт, как с вимом.

Я даже на проде теперь боюсь работать под рутом, нажмешь не туда и приплыли.


Жил я с этой клавиатурой 3 дня, самый важный момент — сначала настроить базовую раскладку и вывести в угол экрана подсказку их entropy, чтобы подглядывать.

Это я хорошо взял еще кейкапы с символами.


После настройки всё встаёт на свои места, спустя сутки ёбнутые привычки меняются и начинаешь привыкать уже к хорошему. Большие пальцы на руках прям маст-хев, можно сказать сразу 6 кнопок на них задействованы, а не только всратый пробел.

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

Даже плагин для обсидиана сделал Cursor Layout Indicator, чтобы выводило под курсором текущую раскладку.

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

Как говорится — жить захочешь, не так раскорячишься.

В связке с niri работает отлично, особенно переходы между окнами радуют.

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

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

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

А ты пользовался такими штуками? Го в комменты!

🛠 #hardware #workflow

💬 Bashdays 📲 MAX 🌐 LF 🔵 Blog
Please open Telegram to view this post
VIEW IN TELEGRAM
157
Kubernetes на минималках

Поднимаем K3s локально и не ноем про инфраструктуру


Кто хочет — ищет способ, кто не хочет — ищет причину.

В четвёртом сезоне Linux Factory мы собираем нормальный отказоустойчивый кубер: три control-ноды, три worker-ноды, HAProxy, Keepalived, VIP, отдельный DNS и хранилище.

Это правильно для обучения инфраструктуре, но даже в минимальной конфигурации получается шесть виртуалок по 2 CPU и 2 ГБ RAM. Не у каждого ноутбук способен переварить такой зоопарк.

Показываю, как поднять настоящий однонодовый кластер K3s на одной VM с 2 vCPU и 2–4 ГБ памяти, подключить kubectl и запустить первое приложение.

👉 https://two.su/epn8r

🛠 #k8s #devops

💬 Bashdays 📲 MAX 🌐 LF 🔵 Blog
Please open Telegram to view this post
VIEW IN TELEGRAM
141
Напьются своих рафов лавандовых, а потом в жопы ебутся…

На фоне переезда на линукс, я знатно упоролся и ушел в сторону разработки. На этот раз я решил закрыть свои гештальты, которые преследовали меня последние несколько лет.

Короче сначала я запили плагин для Obsidian и даже удалось захуячить его в официальный стор плагинов самого обсидиана.

Штуку я назвал Cursor Layout Indicator. Суть такая, что рядом с курсором у тебя отображается маленький индикатор текущей раскладки. Выёбываться я не стал и сделал чисто для RU/EN.

Будь моя воля EN бы я с удовольствием выпилил, но увы, из песни слов не выкинешь.

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

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

Исходники, картинки тут 👉 https://two.su/ml9pj

На этом я не остановился!

Товарищи из mastodon, закинули импрувмент — а что если для всей ОС сделать подобное?

Хе! Чем бы дитя не тешилось. Яж на Niri подсел, ну вот и поперла разработка. Следом был выпущен плагин или хуй пойми че — niri-layout-cursor.

niri-layout-cursor показывает текущую раскладку прямо возле указателя мыши во всей сессии niri. Иконка в системном трее открывает локальные настройки цветов, размера и интеграции с Obsidian.

Интеграция с Обсидиан — если ты ранее ставил самый первый мой плагин, то оно не конфликтует, ну а если не ставил, то из коробки будет все работать.


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

Как ставить и т.п. смотрим тут 👉 https://two.su/fdomd

Не навяливаю, мож у кого-то такие же боли как у меня, потыкайте, всегда готов к диалогу, пулреквестам и т.п. Звездочки мне в хуй не упёрлись, НО не откажусь, так что заранее — спасибо! На халяву и уксус сладкий.

Такие дела!

🛠 #dev

💬 Bashdays 📲 MAX 🌐 LF 🔵 Blog
Please open Telegram to view this post
VIEW IN TELEGRAM
35
Всем привет, с вами TagdTagd!

Я тут вынужденно перешёл на MAX. Просто Telegram перестал работать хорошо. Пришлось разбираться с новым API, переделывать уведомления с Telegram на MAX. Решил вот с вами поделиться опытом — может, кому-то пригодится.

За это время пришлось решить несколько проблем:

1. У MAX под Linux не работал звук. Была проблема с прослушиванием аудио/видео и звонками.

2. MAX постоянно допиливают, поэтому меняются адреса для работы с API.

3. Регистрация бота — небольшой квест, но вполне решаемый. И всё это бесплатно.


Большинство проблем решается с помощью поиска или ИИ. Скрипты брал оттуда же, но пришлось немного адаптировать для себя. Но за неделю разобрался. Всё заработало. Если кому-то понадобится рабочий shell-скрипт для отправки в сообщении текста, файла или текста + файла — пишите, приведу в следующем сообщении.

Первый вопрос

Пропустим: там много разных проблем может быть, но моя решилась после запуска в консоли:

/usr/share/max/bin/max-service/bin/max-service


Нужно было просто доставить библиотеки и создать пару линков.

Второй

Есть несколько адресов для общения с MAX по API:

- https://platform-api.max.ru
- https://platform-api2.max.ru

На данный момент работают оба, но рекомендуют второй. Но у него тоже своя фишка. Он не работает без сертификатов Минцифры.

Третий — регистрация бота

В отличие от Telegram зарегистрировать бота могут только ИП и юрлица.

Делается это всё при наличии квалифицированной электронной подписи. Юрлицо может зарегистрировать до 5 ботов, причём требуется указать их назначение. Каждый бот утверждается модератором. На это уходит до 24 часов, но у меня прошло быстро, часов за 6.

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

🛠 #devops

💬 Bashdays 📲 MAX 🌐 LF 🔵 Blog
Please open Telegram to view this post
VIEW IN TELEGRAM
21
🤖 DevOps в эпоху AI трансформации: что работает уже сейчас!

17 сентября Сбер собирает DevOps-инженеров, SRE и платформенные команды на встречу о том, как AI меняет работу с инфраструктурой, релизами и безопасностью.

Обсудим:
🔘Platform Engineering и IDP: как строить внутренние платформы без лишней сложности
🔘Agentic engineering: каких агентов уже можно доверить пайплайнам
🔘Security на скорости: как закрывать уязвимости, когда счет идет на часы

Своим опытом поделятся практики из Авито, Сбера, Cloud․ru и Т-Банка.

Встречаемся 17 сентября в 17:00 в Сбер.Среде (Москва, Земляной Вал 9А) или онлайн. Мест всего 150 — успей занять своё по ссылке!
Please open Telegram to view this post
VIEW IN TELEGRAM
6
Этот файл был удален пользователем

Встречаемся в Москве с теми, кто отвечает за хранение данных бизнеса. Обсудим, как решить задачу со звездочкой — уберечь массивы файлов и резервных копий от атак шифровальщиков, утечки или случайной перезаписи.

На бизнес-ужине эксперты провайдера ИТ-инфраструктуры Selectel расскажут:
как устроено хранилище S3 под капотом;
какие угрозы данным существуют и как выстроить многослойную систему защиты;
почему защита данных — это не статья расходов, а управление рисками.

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

📆 24 сентября (чт), 18:30
📍Москва, м. Динамо

Участие бесплатное, дождитесь подтверждения заявки. Смотрите полную программу и регистрируйтесь: https://slc.tl/l1n1b

Реклама. АО "Селектел". erid:2W5zFHkyuAy
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Всем привет, с вами TagdTagd. И это вторая часть. Практическая.

С первой частью можешь ознакомиться здесь


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

Поэтому для нормальной работы оповещателя желательно создать группу, добавить туда бота, и от его имени писать.

С определением номеров пользователей и групп разбирался по статье Романа. Там очень хорошо описано.

#!/bin/bash
# Скрипт отправляет текстовое сообщение пользователю или в чат
# $1 "user" для отправки пользователю, "chat" для отправки в чат
# $2 ID пользователя или чата, соответственно
# $3 "Текст сообщения в кавычках"
# $4 "Имя файла в кавычках"
# если файл есть, а текста нет - вместо текста ""
# v 20260812

declare -x PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

set -euo pipefail
exec 1>&2
declare BASE_URL="https://platform-api2.max.ru" # база API + нужны сert минцифры
declare BOT_TOKEN="AAAAAAAAAAAAAAAAAAA_BBBBBBBB_CCCCCCCCCCCCCCCC"

# === Параметры скрипта ===
case "$#" in
0|1|2)
clear
head -6 "$0"
exit 1 ;;
3)
declare FILE="" ;;
*)
declare FILE=$4
if [[ -f "$FILE" ]];then
clear
echo -e "Файл '$FILE' не найден"
exit 1
fi ;;
esac

if [[ -z "$3" && -z "$4" ]]; then
clear
echo -e "Ошибка. Нет текста или файла."
exit 1
fi

declare -l RECEPIENT=$1
declare ID=$2
declare TEXT=$3

case $RECEPIENT in
user | chat )
declare TO_URL="$BASE_URL/messages?${RECEPIENT}_id=$ID" ;;
*)
clear
echo -e "ошибка параметра 1" $RECEPIENT\\n
head -6 "$0"
exit 1 ;;
esac

#declare -p RECEPIENT ID TEXT FILE TO_URL

# === 1. Получить URL для загрузки файла ===
if [[ -n "$FILE" ]]; then
UPLOAD_META=$(curl -s -X POST \
"$BASE_URL/uploads?type=file" \
-H "Authorization: $BOT_TOKEN")

UPLOAD_URL=$(echo "$UPLOAD_META" | jq -r '.url')
if [[ -z "$UPLOAD_URL" || "$UPLOAD_URL" == "null" ]]; then
echo "Не удалось получить URL для загрузки"
echo "Ответ API: $UPLOAD_META"
exit 2
fi

# === 2. Загрузить файл ===
UPLOAD_RESULT=$(curl -s -X POST \
"$UPLOAD_URL" \
-F "data=@$FILE")

# Сохраняем результат загрузки в переменную для вложения
ATTACHMENT_PAYLOAD="$UPLOAD_RESULT"
fi

# === 3. Формируем JSON сообщения ===
# Если есть файл, добавляем attachment
if [[ -n "$FILE" ]]; then
MESSAGE_JSON=$(jq -n \
--arg text "$TEXT" \
--argjson attachment "$ATTACHMENT_PAYLOAD" \
'{
text: $text,
attachments: [
{
type: "file",
payload: $attachment
}
]
}')
else
MESSAGE_JSON=$(jq -n --arg text "$TEXT" '{text: $text}')
fi
sleep 3 # для антифлуда
# === 4. Отправляем сообщение ===

curl -s -X POST \
"$TO_URL" \
-H "Authorization: $BOT_TOKEN" \
-H "Content-Type: application/json" \
-d "$MESSAGE_JSON" | jq .


Сохраняем send_max.sh

chmod +x ./send_max.sh  
/send_max.sh "chat" 123456 "text" "/path/to/file"


🛠 #devops

💬 Bashdays 📲 MAX 🌐 LF 🔵 Blog
Please open Telegram to view this post
VIEW IN TELEGRAM
14