Bash Days | Linux | DevOps
Авторский блог от действующего девопса Самобытно про разработку, devops, linux, скрипты, сисадминство, техдирство и за айтишную жизу. Автор: Роман Шубин Реклама: @maxgrue MAX: https://max.ru/bashdays Курс: @tormozilla_bot Блог: https://bashdays.ru
Показати більше📈 Аналітичний огляд Telegram-каналу Bash Days | Linux | DevOps
Канал Bash Days | Linux | DevOps (@bashdays) у мовному сегменті Російська є активним учасником. На даний момент спільнота об'єднує 23 767 підписників, посідаючи 5 674 місце в категорії Технології та додатки та 28 079 місце у регіоні Росія.
📊 Показники аудиторії та динаміка
З моменту свого створення невідомо, проект продемонстрував стрімке зростання, зібравши аудиторію у 23 767 підписників.
За останніми даними від 24 червня, 2026, канал демонструє стабільну активність. Хоча за останні 30 днів спостерігається зміна кількості учасників на -207, а за останні 24 години на -4, загальне охоплення залишається високим.
- Статус верифікації: Не верифікований
- Рівень залученості (ER): Середній показник залученості аудиторії становить 25.62%. Протягом перших 24 годин після публікації контент зазвичай збирає 14.38% реакцій від загальної кількості підписників.
- Охоплення публікацій: В середньому кожен допис отримує 6 090 переглядів. Протягом першої доби публікація в середньому набирає 3 419 переглядів.
- Реакції та взаємодія: Аудиторія активно підтримує контент: середня кількість реакцій на один пост – 21.
- Тематичні інтереси: Контент зосереджений навколо ключових тем, таких як bashdays, linux, bash, docker, скрипт.
📝 Опис та контентна політика
Автор описує ресурс як майданчик для висловлення суб'єктивної думки:
“Авторский блог от действующего девопса
Самобытно про разработку, devops, linux, скрипты, сисадминство, техдирство и за айтишную жизу.
Автор: Роман Шубин
Реклама: @maxgrue
MAX: https://max.ru/bashdays
Курс: @tormozilla_bot
Блог: https://bashdays.r...”
Завдяки високій частоті оновлень (останні дані отримано 25 червня, 2026), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.
-A INPUT -s xxx.xxx.xxx.xxx/32 -p tcp -m tcp --dport 80,443 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibitedТо порты 80 и 443 так же будут доступны всем желающим. Вот на эти грабли почти каждый и наступает. А решение простое, правим немного свой docker-compose.yml и добавляем networks. В моем примере я добавил сеть bashdays.
version: '3.2' services: nginx: image: nginx:1.20.1 container_name: nginx ports: - '80:80' - '443:443' networks: - bashdays networks: bashdays: driver: bridge driver_opts: com.docker.network.enable_ipv6: "false" com.docker.network.bridge.name: "docker_bashdays"Ну и теперь на хостовой машине можно уже что-то запрещать или разрешать с помощью iptables.
/sbin/iptables -F DOCKER-USER /sbin/iptables -I DOCKER-USER -i eth0 -o docker_bashdays -j DROP /sbin/iptables -I DOCKER-USER -i eth0 -s <EXTERNAL IP> -j RETURN /sbin/iptables -I DOCKER-USER -i eth0 -p tcp --dport 80 -s <CLIENT IP> -j RETURN /sbin/iptables -I DOCKER-USER -i eth0 -p tcp --dport 443 -s <CLIENT IP> -j RETURN /sbin/iptables -I DOCKER-USER -i eth0 -o docker_bashdays -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPTГде <EXTERNAL IP> это айпишник сервера который доступен из мира. А <CLIENT_IP> собственно айпишник клиента, которому мы разрешим конектится к порту 80 и 443. Все! Теперь у нас и docker в шоколаде и хостовые правила iptables работают «наверное» правильно. Не забывай правильно подставить свой интерфейс ethX/enoX, а то всякое бывает. Важное замечание. После перезапуска контейнеров, docker снова перетрет правила на хостовой машине. Поэтому весь этот процесс хорошо бы автоматизировать. Я сильно не заморачивался, просто закинул правила в bash скрипт, повесил на крон (каждую минуту), да и все. Закостылил так закостылил 🧠 Сегодня чуть позже покажу более правильный скрипт, который будет следить за ребутом docker, но по сути те же яйца, только сбоку. Раз был всех вас видеть! tags: #networks — 🟢 Подпишись: @bashdays
- балансировщик (белый айпишник) - фронтэнд (192.168.0.3) - бекэнд (192.168.0.4) - база (192.168.0.5)У [балансировщика] есть белый айпишник, у остальных (фронтэнд, бекэнд, база) только серые. Хм… ну и как prometheus будет ходить на серые инстансы и забирать метрики? Да никак! 🤒 Уффф. Пошел смотреть в сторону pushgateway, чтобы инстансы сами метрики пушили в prometheus или сразу в VictoriaMetrics. VictoriaMetrics — быстрая и масштабируемая СУБД для хранения и обработки данных в форме временного ряда (запись образует время и набор соответствующих этому времени значений, например, полученных через периодический опрос состояния датчиков или сбор метрик). Но тут снова грабли. У prometheus тоже нет белого айпи. Это провал! Какой-то замкнутый круг получается. Забрать метрики не можем, отдать тоже не можем. Выдавать белые айпишники ой как не хочется, по причине — лень настраивать фаерволы и прочую шляпу. Но что же делать? Правильно — достаём костыли! Так как у тестовых серверов на [балансировщике] есть белый ip адрес, будем привлекать iptables и жёстко роутить. На балансировщике с белым ip, выполняем:
-A PREROUTING -p tcp -m tcp --dport 1001 -j DNAT --to-destination 192.168.0.3:9100 -A PREROUTING -p tcp -m tcp --dport 1002 -j DNAT --to-destination 192.168.0.4:9100 -A PREROUTING -p tcp -m tcp --dport 1003 -j DNAT --to-destination 192.168.0.5:9100 -A POSTROUTING -j MASQUERADEИдея заключается в том, что с портов 1001-1003 (на балансировщике) мы попадаем на внутренние инстансы с серыми айпишниками и забираем свои метрики с портов 9100. А в prometheus говорим, иди на внешний айпишник балансировщика с портами 1001-1003 и выгребай данные с серых инстансов. prometheus.yml
---
- targets:
- balancer:1001
labels:
env: test
role: frontend
- targets:
- balancer:1002
labels:
env: test
role: backend
Красота! Кейс рабочий, костыли присутствуют, графики красивые, тестировщики довольные. Ну а что еще надо? Think different! 🧠
tags: #рабочиебудни #monitoring #networks
—
🟢 Подпишись: @bashdayswhois <domain> и получаем желаемое. Но это не работает с доменной зоной .to. Если не веришь, можешь самостоятельно убедиться. Получишь массу информации, но никак не значение Expires on.
Отправляемся на раскопки.
Существует корневой whois сервер не для доменов, а для зон. Называется он whois.iana.org. С помощью него можно получить данные по конкретной зоне, контакты, телефоны и т.п.
Проверяю нужную мне зону .to
whois to -h whois.iana.org whois: whois.tonic.to status: ACTIVE remarks: Registration information: http://www.tonic.to/ created: 1995-12-18 changed: 2022-06-01 source: IANAОтдается куча информации. И что мне с этим делать? 😐 Ладно, я парень настырный. Пробую так:
whois best.to -h whois.tonic.toПолучаю тот же ответ что и раньше, ну нет нигде Expires on, шляпа какая-то. В ответе вижу строчку:
remarks: Registration information: http://www.tonic.to/
Ок. Раз ничего не получается, самое время идти читать документацию, может в ней будет что-то полезное.
Натыкаюсь на такой пункт: Предоставляет ли Tonic услугу whois? Компания Tonic не поддерживает базу данных whois, содержащую информацию о владельцах регистраций, поскольку многие наши клиенты считают, что публичное размещение такой информации нарушает их частную жизнь. Более того, мы никогда не будем продавать списки рассылки наших клиентов.
Приехали. Но чуть ниже вижу: всю доступную информацию по домену, ты можешь попробовать получить по ссылке: https://www.tonic.to/whois?best.to
А давай попробуем, вариантов у нас не много:
curl https://www.tonic.to/whois?best.to <pre> Domain: best.to Created on: Fri Apr 23 02:27:04 2021 Last edited on: Sat May 27 06:48:58 2023 Expires on: Sun Apr 28 07:33:28 2024 Primary host add: None Primary host name: ns-494.awsdns-61.com Secondary host add: None Secondary host name: ns-1424.awsdns-50.org ENDОПА! Есть контакт, Expires on как на ладони. Можно двигать таску в Done и писать экспортер для prometheus. И возможно однажды alertmanager вовремя сообщит, что стоило бы продлить домен, но это не точно 😎 После плановой интеграции про тимлидов, закину тебе еще какое-нибудь интересное чтиво. На связи! tags: #networks — 🟢 Подпишись: @bashdays
scp -r user@bashdayz:/tmp/nginx.log /home/user/tmp/
- скинуть файл человеку в слак/маттермост
- если файл большой, выложить его на корпоративный google drive
- скинуть человеку ссылку на файл на корпоративном диске
scp (Secure CoPy) — утилита для безопасного копирования данных между Linux-системами по протоколу SSH
Тут подходит фраза из мема: вот это chmod +x /usr/local/sbin/trans.
Запускается всё это безобразие так: trans <файл>
#!/bin/bash
SIZE=1000000
if [ -n "$(find "$1" -prune -size +"$SIZE"c)" ]; then
tar -czvf /tmp/$1.tar.gz $1
curl --upload-file /tmp/$1.tar.gz https://transfer.sh/$1.tar.gz
rm /tmp/$1.tar.gz
else
curl --upload-file $1 https://transfer.sh/$1
fi
Логика такая:
1. Если размер файла > 1 мб, то сжимаем
2. После сжатия загружаем файл в сервис transfer.sh
3. Подчищаем за собой
4. Если файл < 1 мб, то просто загружаем как есть в тот же сервис transfer.sh
5. После загрузки в консоль выводится ссылка для скачивания
6. Копируем полученную ссылку и передаем разработчику
7. Профит. Минимум действий, максимум удобства
Сервис transfer.sh это очень удобная и простая штука, которая позволяет обмениваться файлами с помощью curl/wget. Без регистрации и смс. Лимиты приличные 10гигов на файл, 14 дней хранятся на сервере. Есть возможность зашифровать перед отправкой и проверить на вирусы. И все это бесплатно.
А еще в curl можно передать заголовки -H "Max-Downloads: 1" -H "Max-Days: 5" и тогда файл разрешат скачать только один раз, а через пять дней он сам удалится. Пожалуй очень удобно.
Тут конечно возникает вопрос — эммм, но это же не безопасно? Конечно не безопасно, поэтому годится лишь для передачи какой-то некритичной информации. А я передаю чисто логи, в них ничего критичного нет.
Ну а если хочется передать сканы документов или реквизиты банковских карт, то в мой скрипт ты можешь встроить gpg шифрование. Либо переделать сжатие на 7z и зашифровать по максимуму. Но опять же не рекомендую, лучше передавай важные документы другим, более безопасным способом.
Мысли в слух: Вот есть корпоративный google диск, хранишь ты там абсолютно всё, включая секреты компании. Безопасно? НЕТ! Гугол давно уже у тебя всё спёр и всё про всех знает. Так что можно булки расслабить и перестать параноить. Ладно, опять в лирику ударились.
Короче бери на заметку, дорабатывай, переделывай. Можешь добавить xclip/pbcopy чтобы ссылка автоматом в буфер обмена копировалась. Ну и зайди на сайт transfer.sh и посмотри все возможности, которые они предоставляют. Там все с примерами, разберется любой.
Удобно? Удобно! А главное максимально просто. Хорошо тебе провести остаток выходных, ну и увидимся!
tags: #bash #services
—
🟢 Подпишись: @bashdaysapt/yum install ccze
Ну а после установки, применяем на практике:
cat /var/log/syslog | ccze -AКлюч
-A = Generate raw ANSI output
Вместо cat можно иcпользовать и tail, чтобы логи бежали в реальном времени. Я к примеру при дебаге использую исключительно tail.
tail -f /var/log/syslog | cczetail позволяет выводить новые строки в интерактивном режиме, либо выводить заданное количество строк с конца файла. Ура, теперь у нас настоящая новогодняя ёлка! От серых будней ничего не осталось, все чётенько, по цветам, ошибки промаркированы. Пушка! А самая приятная киллер-фича этой утилиты, это то, что я могу записать логи в html файл. А затем передать этот файл разработчикам, которые частенько приходят с просьбой — Олег, выгрузи нам пожалуйста последние 500 строк.
tail -n 500 /var/log/auth.log | ccze -h > ~/log.htmlРаз и готов html файл, который можно открыть в браузере и посмотреть как иностранные бедолаги с дикого запада пытались подобрать пароль на 22 порт. И всё это будет в цвете! У утилиты ccze есть много других ключей, а также присутствует поддержка плагинов. Но я пользуюсь функционалом из коробки. Список доступных плагинов можно глянуть командой:
ccze -lНу а если есть желание что-то там перепилить по цветам и т.п. всё это можно сделать в конфигурационном файле:
/etc/cczerc
Короче бери на вооружение, утилита мастхев. Картинка к посту опять не влезла, заливаю на телеграф, чтобы ты смог посмотреть на эту новогоднюю гирлянду и решить, что она тебе тоже ой как необходима.
✅ Картинка с ccze
В следующем посте расскажу как быстро передавать разработчикам подобные файлы, не мучаясь со скачиванием их на локальную машину, а затем приседать с пересылкой через слак/маттермост.
Давай краба, подписывайся, тыкай палец вверх, увидимся!
tags: #linux #utils
—
🟢 Подпишись: @bashdaysprintf '%s\n' {a..d} > /tmp/test.txt
либо так:
echo {a..d} > /tmp/test.txt
После создания файла, нужно запустить команду sync, но можно и не запускать, спустя несколько секунд linux сам всё нужное сделает. Я запускаю, потому что мне важна чистота эксперимента.
sync — утилита Unix, предназначенная для обновления файловых систем и для синхронизации данных на диске с данными в памяти. При этом выполняется системный вызов sync, который вызывает запись всех буферизованных изменений метаданных файлов и данных в базовые файловые системы. Он гарантирует, что все, что хранилось в памяти, будет записано на диск, предотвращая потерю данных, хранящихся в кеше, при аварийном завершении работы.
Так, файл успешно создан, давай посмотрим что внутри:
cat /tmp/test.txt abcdОк. Теперь давай узнаем физическое расположение файла на диске, для этого запускай команду:
filefrag -b512 -v /tmp/test.txtПрограмма filefrag (из пакета e2fsprogs) показывает насколько сильно фрагментирован файл. После выполнения команды, смотрим результат. Нам важна колонка: physical_offset в моём случае я получил такие значения:
4612136..4612143Отлично. Теперь я знаю точное расположение файла на жестком диске. А давай прочитаем его прям с диска! Для этого стартуем:
sudo dd if=/dev/sda1 skip=4612136 status=none count=8Важно правильно указать свой диск /dev/sdX. Ну и в параметр skip подставить первое значение из колонки physical_offset По итогу запуска, я получаю туже картину. Только без применения сторонних утилит вроде cat и т.п..
abcdНу и вишенка. Если я удалю файл
rm /tmp/test.txt и затем выполню предыдущую команду:
sudo dd if=/dev/sda1 skip=4612136 status=none count=8То получу тот же вывод «abcd», потому что файл на диске продолжает лежать и занимать место. Это визуально он исчез, чтобы тебе глаза не мозолить. Но зная его physical_offset вполне можно до него дотянутся и восстановить при желании. Полезно? Полезно! Для чего это можно применить? Нууу не знаю, коллега к примеру таким образом восстанавливал базу данных, которую в пятницу вечером решили случайно удалить. А бэкапы съели мыши.🐁 Кстати успешно восстановил. Ну это уже лирика… Очередную порцию полезных знаний я тебе выдал, ставь лайк, изучай. Увидимся! 😻 tags: #linux #bash — 🟢 Подпишись: @bashdays
/usr/local/sbin/cheat_shit.sh чмодим chmod +x cheat_shit.sh чтобы он в экзешник превратился.
#!/bin/bash tput civis tput smcup tput cup 0 0 trap 'tput rmcup;tput cvvis' EXIT echo 'Hello,this is Cheat-Shit' echo '------------------------' echo 'а тут можешь написать всё, что захочешь' echo '------------------------' echo 'source: https://t.me/bashdays' read -srn1 -t 0.7 while read -srn1 -t 0.1 do : done exitОЧЕНЬ СТРАШНО! Держу пари мало кто про такое вообще слышал и тем более видел. Но такое в bash вполне реализуемо и в школе такому не научат. Кратенько:
tput civis = скрываем курсор
tput smcup = переходим на альтернативный экран
tput cup 0 0 = переводим курсор в начало строки
trap 'tput…' = после выхода зачищаем весь мусор
Далее прописываем бинд в ~/.bashrc и вешаем вызов скрипта на CTRL+h
bind -x '"\C-h":"/usr/local/sbin/cheat_shit.sh"'Перезапускаем сессию. Теперь при нажатии CTRL+h у меня поверх рабочей консоли открывается попап с нужным мне текстом. В тексте может быть шпаргалка либо котик 😑 либо что-то еще полезное. Как повторить для zsh, ХЗ, я не разбирался. Если будут наработки, скидывайте в бота, сделаю отдельный пост. Ну и для гиков, кто хочет покопаться поглубже, можешь зама́нить и захелпить:
man 3 readline man bash (раздел readline) man tput man stty help trap help read help bind man 5 terminfoПомимо шпаргалки по хоткею, ты можешь запустить вообще любой скрипт. Тут уже зависит от полета фантазии. Больше не смею тебя отвлекать, спасибо за внимание. Давай пять и погнали дальше отдыхать! ✅ ВИДЕО КАК ЭТО РАБОТАЕТ tags: #bash — 🟢 Подпишись: @bashdays
#!/bin/bash
COUNT_Q=$(ssh user@bashdayz-d1 rabbitmqctl list_queues | grep 'email.send.mass'|awk '{print $2}')
if [ $COUNT_Q -gt 500 ]
then
su - amqp-daemon -c "cd ~/daemon && daemon.pl stop"
su - amqp-daemon -c "cd ~/daemon && daemon.pl start"
fi
Разбор скрипта:
Скрипт работает в кроне на сервере рядом с микросервисом. Запускается каждые полчаса. После запуска, он подключается по ssh к серверу с очередями RabbitMQ. Проверяет общее количество писем в очереди email.send.mass. Если писем скопилось более 500, то значит ПРИПЛЫЛИ!
Оператор -gt в bash означает: Больше
А конструкция su - amqp-daemon -c означает, что запускаем команды от пользователя amqp-daemon
Ну а далее срабатывает логика перезапуска микросервиса, остановка и запуск.
Профит. Клиент доволен как слон, а мы при деньгах. 💰
Не забывыем прописать ssh public ключи, чтобы скрипт мог ходить на другие сервера без пароля. Ну про это ты должен знать. Если не знаешь, то обязательно погугли как работают ssh ключи, это база.
Также можно сюда прикрутить логирование, оповещения, экспортер в prometheus и на графиках в grafana все красиво вывести. Когда чо упало, когда перезапустилось, пустая ли очередь и т.п.
Переработав этот скрипт под свои нужды, можно получать вообще любые данные с любых серверов, не используя экспортеры. Ну и в дальнейшем строить логику в скрипте на этих данных. А самое главное это быстро реализуемо. Костыльно? Конечно! Но клиент всегда прав, а богатый клиент прав в двойне. Рабочие будни 😎
С пятницей ребят! Всем хороших предстоящих выходных и самое главное — берегите себя.
tags: #bash
—
🟢 Подпишись: @bashdays/mnt/storage:
sshfs -o compression=no,allow_other,reconnect storage@bashdayz.ru:/storage /mnt/storage
compression - не использовать компрессию
allow_other - разрешить доступ к шаре
reconnect - нативный реконект если шара отвалилась
Из плюсов: на baremetal сервере не надо устанавливать никакой дополнительный софт, все работает по протоколу ssh.
Но есть нюансы. Допустим если ноду перезагрузить, то всё отвалится. Либо придут сетевые ножницы и оно тоже отвалится.
Запихать в fstab не вариант. Так как на этапе маунта еще нет сети и загрузка сервера просто остановится в попытках примонтировать шару. А ключик reconnect работает как ему захочется, даже если выставить таймауты проверок.
Решение простое, создаем три юнита в systemd.
✅ Первый юнит (АААААРРРРРР!!!!! В пост не влазиет, да и форматирование тут убогое, публикую в телеграфе)
After=network.target - запускать маунт только после того, как на хосте поднимется сеть
What=storage@bashdayz.ru:/storage - что монтируем
Where=/mnt/storage - куда монтируем
Важно! Файл юнита должен называться в соответствии с путем куда монтируем. Узнать имя можно командой:
systemd-escape -p /mnt/storageПервый юнит сохраняем сюда:
/etc/systemd/system/mnt-storage.mount
Теперь нужно сделать юнит проверки, если шара отвалилась. Для начала создаем юнит с таймером:
✅ Второй юнит
After=mnt-storage.mount - обеспечит запуск таймера после загрузки сервера, но только после того, как маунт юнит будет запущен, то есть после того, как удалённая ФС смонтируется.
Unit=mnt-storage.service - какой юнит будем запускать при срабатывании таймера. О нём чуть ниже.
OnCalendar=*-*-* *:*:00 - это означает каждую минуту.
Юнит-файл таймера можно называть как угодно. Но чтобы было понятнее, будем называть также, как и маунт-юнит. Итак, сохраняем в /etc/systemd/system/mnt-storage.timer
Теперь нужно создать юнит, который будет заниматься проверкой маунта и его перезапуском при необходимости:
✅ Третий юнит
Здесь всё просто. Bash строка в ExecStart это bash’евый однострочник, проверяющий наличие маркерного файла mount.yes, при отсутствии которого будет перезапущен маунт-юнит. В более новой версии systemd можно было бы это всё сделать иначе, но зато такой вариант более универсален.
Cохраняем в /etc/systemd/system/mnt-storage.service
Релодим и активируем
systemctl daemon-reload systemctl enable mnt-storage.mount systemctl enable mnt-storage.timerТретий юнит mnt-storage.service при загрузке сервера активировать не нужно, поскольку этот юнит вызывается таймером mnt-storage.timer. Он будет всегда Active: inactive (dead), это нормально. Ну и в финале запускаем таймер:
systemctl start mnt-storage.timerВот и все! Наша шара успешно взята под контроль, подключена. А в случае отвала по любым причинам, она сама перемонтируется без лишних вопросов. Ну и после перезагрузки ноды, тоже все поднимется из коробки. Способ рабочий, полет стабильный более трёх лет. Можешь приспособить к своим каким-то изобретениям и использовать уже юниты, а не закроненные bash скрипты. А шары монтировать через sshfs, а не через вонючий, разваливающийся gluster. Фак еее! 🐄 tags: #linux — 🟢 Подпишись: @bashdays
Out of Memory: Killed process 2256 (mysql) score 907 or sacrifice childА это уже не шутки. Если к тебе стал приходить OOM Killer, значит в какой-то момент на сервере, что-то
cat /proc/<PID>/oom_scoreГде PID это идентификатор процесса, узнать можешь командой ps ax|grep postfix В результатах ты увидишь число, к примеру: 826, это и есть очки негодности. Если интересно как начисляются очки негодности, я вынес это в отдельный пост в телеграф, чтобы не валить тебя скучной теорией. Почитать можешь тут: ✅ Как вычисляются очки негодности? TL;DR Если подытожить, то OOM Killer убьет самый «жирный» процесс, который наименее активен в системе и имеет самое короткое время жизни. Как обуздать OOM Killer? 🔪 Можно вообще его отключить! Но по понятным причинам, это все равно что отключить жизненно важный орган у человека. Какое-то время он еще проживет, но потом обязательно сдохнет в kernel panic. Отключается командой:
sudo echo 1 > /proc/sys/vm/panic_on_oomПо умолчанию 0 (то есть включено). Я ни разу не встречал, чтобы кто-то отключил этот функционал, но достаточно много раз сталкивался с забиваем костылей в сами процессы. Можно повысить или понизить репутацию для процесса, добавив в файл oom_adj значение от -17 до +15. Для повышения репутации выполняем команду:
sudo echo -6 > /proc/<PID>/oom_adjНе забываем подставить в PID, идентификатор нужного процесса. Для отключения OOM Killer для определенного процесса, выставляем репутацию -17. Теперь этот процесс в «домике» и его никакая собака не посмеет тронуть.
sudo echo -17 > /proc/<PID>/oom_adjНо если ты рестартанешь процесс, у него изменится PID. А репутация, которую ты ему уже накрутил, может примениться к совсем другому процессу таким же PID. Так же можно динамически определять PID процесса и менять ему репутацию. Закинуть это в крон и прыгать от счастья:
pgrep -f "/usr/sbin/sshd" | while read PID; do echo -17 > /proc/$PID/oom_adj; doneНо правильнее задать очки в самом systemd, в юните для сервиса, этот параметр:
[Service] OOMScoreAdjust=-500Собственно это база. По опыту скажу так — если к тебе пришел OOM Killer, сервак можно смело перезагружать. Нихрена там уже не работает, несмотря на всякие очки и коэффициенты. Перезагрузиться будет намного эффективнее, чем пытаться поднять что-то. Поднял, а потом уже по горячим следам и логам, дебаж. Поздравляю, ты только что прокачался еще на один уровень. Хорошего тебе понедельника, да и лёгкой рабочей недели! Увидимся! 🐾 tags: #linux — 🟢 Подпишись: @bashdays
$EDITOR. Ты снова скажешь — да CTRL+x+e (а в osx кнопка CTRL со значком ^).
Как нажать CTRL+x+e и не сломать пальцы? Сначала зажимаешь и удерживаешь CTRL, следом жмешь x и не отпуская CTRL жмешь e.
📺 Тырым-Пырым и перед тобой уже твой любимый vim/mcedit/nano/другойshit
Если получил ошибку: External editor requested but $VISUAL or $EDITOR not set. Не расстраивайся, выполни эти команды и у тебя все заработает. Вместо nano подставь своё.
EDITOR=$(which nano) export EDITOR=$EDITORЛибо на постоянку добавь в
~/.bashrc или ~/.zshrc и не забудь перечитать эти файлы: source ~/.bashrc && source ~/.zshrc
which — команда используется для определения местоположения данного исполняемого файла, который выполняется при вводе имени исполняемого файла (команды) в строке терминала. Команда ищет исполняемый файл, указанный в качестве аргумента, в каталогах, перечисленных в переменной среды PATH.
Есть еще команда select-editor, но не везде присутствует, она сразу список всех редакторов выведет в читабельном виде, тебе останется лишь выбрать циферку. Редактор установится глобально в системе без правки .bashrc/zshrc.
Так, ушли от темы, короче вызвал ты свой любимый редактор и не сломал пальцы. А дальше? А дальше накидываешь в нем скрипт или команды, которые тебе нужно выполнить в оболочке bash/zsh.
Размеренно, удобно, с подсветкой синтаксиса и хоткеев, а если у тебя прокаченный vim, так вообще полноценная IDE получается.
Накидал? Сохраняешь! Сохраняется по умолчанию во временную папку: /tmp/bash-fc.GpOzlI
И после закрытия, все команды из файла автоматически выполняются, а временный файл удаляется. Все введенные команды и выхлоп по ним продублируются в консоли. Так что не переживай, ничего не CTRL+x+e, вставляю туда свою портянку, сохраняю и иду в кроватку принимать горизонтальные процедуры.
А еще если ввел какую-то длинную команду в консоли и хочешь ее сохранить отдельным скриптом, жмешь хоткей ctrl+x+e и вуаля, открывается редактор и в нем уже вставлена эта команда. Сохраняешь в папке ~/Downloads и забываешь про этот файл навсегда.
Почему не ansible? Хм, можешь и плейбуки написать. Хозяин барин. Но у нас тут про комфортную работу в консоли. Про ansible тоже посты будут, но попозже.
Практично, удобно, всё работает из коробки. А мы с тобой такое любим. Вот такие пироги! Ну и с пятницей друзья, всем хороших предстоящих выходных, берегите себя.
PS: Кстати выйти из vi/vim можно командой :q! Это тебе бонус на всякий случай 👋
tags: #bash #linux
—
🟢 Подпишись: @bashdaysexport HISTTIMEFORMAT="%d/%m/%y %T "И вывод будет примерно таким:
369 20/07/23 15:46:54 flask run 370 20/07/23 15:46:54 /usr/bin/python3 371 20/07/23 15:46:54 python --version 372 20/07/23 15:46:54 python3 --version 373 20/07/23 15:46:54 ps ax|grep python 374 20/07/23 15:46:54 sudo kill -9 30049 375 20/07/23 15:46:54 brew install pyenvЛибо можешь прописать это в
~/.bashrc чтобы export выполнялся автоматически:
echo "export HISTTIMEFORMAT=\"%d/%m/%y %T \"" >> ~/.bashrcПрекрасно, теперь намного нагляднее. Идем дальше. Давай перекрасим временные маркеры в синий цвет, чтобы более лаконично выглядело.
export MY_BASH_BLUE="\033[0;34m"
export MY_BASH_NOCOLOR="\033[0m"
export HISTTIMEFORMAT=`echo -e ${MY_BASH_BLUE}[%F %T $MY_BASH_NOCOLOR `
Эти экспорты можешь так же закинуть в ~/.bashrc и затем выполнить команду source ~/.bashrc чтобы не перезагружать сессию и применить настройки в моменте.
Окей, но как же быть с оболочкой zsh? Сейчас и в ней сделаем нечто подобное.
Из коробки zsh, ты можешь воспользоваться командой:
history -Eвывод будет таким:
9481 9.5.2023 16:04 export FLASK_RUN_PORT=8888 9482 9.5.2023 16:04 export FLASK_APP=index.py 9483 9.5.2023 16:04 flask run 9484 9.5.2023 16:08 export TGS_API_KEY=12345 9485 9.5.2023 16:08 flask runУже более менее информативно, а если так:
history -iопа-опа-опапа:
9481 2023-05-09 16:04 export FLASK_RUN_PORT=8888 9482 2023-05-09 16:04 export FLASK_APP=index.py 9483 2023-05-09 16:04 flask run 9484 2023-05-09 16:08 export TGS_API_KEY=12345 9485 2023-05-09 16:08 flask runВидим другой формат даты. Вообще ключей для форматирования даты достаточно много, можешь почитать на досуге если интересно:
man zshoptions man zshbuiltinsНу а чтобы каждый раз не вводить ключи, сделай нужный тебе alias в
~/.zshrc
alias history="history -i"А еще есть такая утилита как «fc», я думаю большинство про нее вообще ничего не слышали. fc — unix-утилита, служащая для редактирования списка ранее введенных команд, а также их выполнения. Вот тебе команда на основе fc, которая выведет историю, сразу же с временными маркерами:
fc -li 100Больше уж и сказать нечего, основное разобрали, внедряй. Еще есть и другие оболочки типа fish, но так как я ими не пользуюсь ежедневно, то и рассказывать вам про них сегодня не буду. А завтра снова пятница, неделя прям в трубу вылетела. Давайте, увидимся. 🐱 tags: #bash #linux — 🟢 Подпишись: @bashdays
stat -c'%z' /proc/self/statВременные метки [atime, mtime, ctime] будут равны времени создания [inode] для этого «файла». В данном случае это время обращения к данному файлу. Вообще proc сама по себе интересная штука. Почти для каждого файла есть свой набор функций для стандартных операций [read, write, open и т.п.].
2023-07-18 11:42:22.592640126 +0000А еще получить желаемое можно с помощью утилиты «ps»
ps --no-headers -o lstart -C psВремя и дата равны времени запуска процесса ps
Tue Jul 18 11:44:07 2023Следом идет команда «printf»
printf '%(%c)T\n'Это встроенная команда в оболочку Bash. Выводится дата и время в соответствии с установленной локалью.
Tue Jul 18 11:44:53 2023А еще можно так:
( T='\t' ; echo ${T@P} )
( T='\T' ; echo ${T@P} )
( T='\@' ; echo ${T@P} )
( T='\A' ; echo ${T@P} )
( T='\D{%X%t%x}'; echo ${T@P} )
${parameter@P} начиная с версии bash 4.4
16:16:22 04:16:26 04:16 PM 16:16 16:16:39 07/18/23Ну и фаталити на закусочку, выведем unixtime тремя разными способами. Эквивалентно команде:
date '+%s'
printf '%s\n' "$EPOCHREALTIME" printf '%s\n' "$EPOCHSECONDS" printf '%(%s)T\n' 1689686418.954954 1689686418 1689686418Вообще редко такое может пригодиться, но пару раз на собесах какие-то упоротые техдиры задавали подобный вопрос. Не знаю откуда они такое берут, но факт остается фактом. Разнообразь свои скрипты такими замысловатыми конструкциями и ни один девопс (кроме тебя естественно) нихрена не поймёт. Создашь басфактор и будешь самым незаменимым в коллективе 😠 пам пам пам Всем добра котики! tags: #bash #linux — 🟢 Подпишись: @bashdays
HUY.txt, давай создадим его командой:
echo '12345' > HUY.txtОпыты проводим над утилитой
sed. Исследовать будем команду:
sed -i.tmp 's/1/2/' HUY.txtКлюч
-i означает редактирование файла на месте, принимает необязательный суффикс tmp. Если суффикс задан, то будет создана копия файла с предыдущим содержанием.
Команда s/// это команда замены, одного на другое. То есть в примере мы меняем (1) на (2) в файле HUY.txt
Погнали изучать кишки
strace -ye '/^open',read,write,rename,close sed -i.tmp 's/1/2/' HUY.txtВыведет
1. openat(AT_FDCWD, "HUY.txt", O_RDONLY) = 3</tmp/HUY.txt>
2. openat(AT_FDCWD, "./sedvKFsXv", O_RDWR|O_CREAT|O_EXCL, 0600) = 4 </tmp/sedvKFsXv>
3. read(3</tmp/HUY.txt>, "12345\n", 4096) = 6
4. read(3</tmp/HUY.txt>, "", 4096) = 0
5. close(3</tmp/HUY.txt>) = 0
6. write(4</tmp/sedvKFsXv>, "22345\n", 6) = 6
7. close(4</tmp/sedvKFsXv>) = 0
8. rename("HUY.txt", "HUY.txt.tmp") = 0
9. rename("./sedvKFsXv", "HUY.txt") = 0
10. close(1</dev/pts/0>) = 0
Теперь разберем построчно, что же произошло:
1. Открывается файл HUY.txt
2. Открывается временный файл sedvKFsXv
3. Из файла HUY.txt читаются 6 байт 12345\n
4. Пробует прочитать еще раз HUY.txt, вернулось 0 байт, найден конец строки
5. Закрывается файл HUY.txt
6. Записывается 6 байт 22345\n во временный файл sedvKFsXv
7. Закрывается временный файл sedvKFsXv
8. Переименовывается файл HUY.txt в HUY.txt.tmp
9. Переименовывается временный файл sedvKFsXv в HUY.txt
10. Что-то там где-то опять закрывается
Если подытожить получилось такое:
- Считывается исходный файл HUY.txt
- Во временный файл sedvKFsXv записывается обработанный текст
- Исходный файл HUY.txt становится резервной копией HUY.txt.tmp
- Временный файл sedvKFsXv становится текущим HUY.txt
Что нам дал этот эксперимент?
А дал он нам то, что всё работает. И теперь у нас есть понятие как это работает.
Допустим столкнулся ты с проблемой, что sed не смог что-то записать и ты не понимаешь почему. Запускаешь strace и смотришь почему:
write(4</tmp/sedvKFsXv>, "strace: exec: Permission denied\n", 6) = 6Опа, а прав на запись в папку
/tmp нет, возможно какой-то лось дырявый запретил туда запись. Отдебажили, фиксим: выставляем 3 топора (chmod 777) на папку /tmp и радуемся какие мы молодцы.
Этот способ отладки ты можешь применить не только для sed, но и для своих скриптов, программ, сервисов и т.п. Как нибудь в будущем поэкспериментируем с php и Битриксом 🤡
Как-то так. Ничего же сложного? Ну вот и я про тоже. Главное не боятся и знать куда смотреть. Ну а я тебе покажу куда смотреть и проведу тебя протоптанными дорожками.
Ладно, пойду пельмени жарить, всем хорошего понедельника! 💗
tags: #debug
—
🟢 Подпишись: @bashdays
Вже доступно! Дослідження Telegram за 2025 — головні інсайти року 
