ch
Feedback
BashTex | Linux

BashTex | Linux

前往频道在 Telegram

Авторский канал для тех, кто хочет глубже погрузиться в мир Linux. Подойдет для разработчиков, системных администраторов и DevOps Реклама: @dad_admin

显示更多
2 524
订阅者
无数据24 小时
-67
+230
帖子存档
🌐 Сети для всех — сообщество для тех, кто хочет разобраться в компьютерных сетях и системном администрировании. 👉 Наш Telegram-канал: https://t.me/Networks_anyone Внутри сообщества вас ждет: - практические задания и разборы - понятная теория без воды - видеолекции и примеры конфигураций - обсуждение реальных и нестандартных сетевых задач - помощь и живое общение с единомышленниками 🎓 Курсы команды «Сети для всех»: 1️⃣ Компьютерные сети (Cisco — введение) https://stepik.org/a/227855 2️⃣ Компьютерные сети (Cisco — продвинутый уровень) https://stepik.org/a/230932 3️⃣ Компьютерные сети (MikroTik — практическое администрирование) https://stepik.org/a/260615 👥 Более 300 студентов уже с нами — присоединяйтесь к сообществу и прокачивайте сети вместе с нами. Сети для всех — понятно, практично, по делу. #СетиДляВсех #NetworksForAll

Проверка существования команды и версии утилиты Скрипты часто падают не из-за логики, а из-за отсутствующей команды или неподходящей версии утилиты. Хорошая практика для часто переезжающих скриптов - проверять наличие команды до выполнения основной логики и иметь fallback. ▪️ Базовая проверка: есть ли команда

if ! command -v curl >/dev/null 2>&1; then
    echo "curl не найден"
    exit 1
fi
command -v в данном случае: быстрее и безопаснее which; корректно работает с alias и builtins; не пишет лишнего в stdout. ▪️ Проверка с fallback

if command -v curl >/dev/null; then
    DL="curl -fsSL"
elif command -v wget >/dev/null; then
    DL="wget -qO-"
else
    echo "Нет curl или wget"
    exit 1
fi

$DL https://bashtex.com
Один интерфейс - разные реализации. ▪️ Проверка версии утилиты

REQ="7.60"

CUR=$(curl -V | awk '{print $2}')

if [ "$(printf '%s\n' "$REQ" "$CUR" | sort -V | head -n1)" != "$REQ" ]; then
    echo "curl слишком старый: $CUR"
    exit 1
fi
sort -V корректно сравнивает версии (7.9 < 7.10). ▪️ Универсальная функция

require_cmd() {
    command -v "$1" >/dev/null || {
        echo "Требуется команда: $1"
        exit 1
    }
}
Использование:

require_cmd awk
require_cmd tar
BashTex 📱 #bash #utils

Проверка доступности DNS и fallback на другой сервер Когда DNS внезапно падает, проблемы выглядят как сбой сети или сервиса. Чтобы не гадать, можно сделать простой механизм: проверяем DNS и если не отвечает, то временно переключаемся на резервный сервер. 🛠 Базовый скрипт

#!/bin/bash

TEST_DOMAIN="google.com"
PRIMARY_DNS="8.8.8.8"
FALLBACK_DNS="1.1.1.1"
RESOLV="/etc/resolv.conf"
BACKUP="/tmp/resolv.conf.bak"

if dig +time=2 +tries=1 "$TEST_DOMAIN" @"$PRIMARY_DNS" > /dev/null; then
    echo "DNS доступен"
    exit 0
fi

echo "DNS недоступен, переключаемся на fallback"

cp "$RESOLV" "$BACKUP"

cat > "$RESOLV" <<EOF
nameserver $FALLBACK_DNS
EOF
dig - быстрая проверка реального DNS-запроса +time и +tries - не зависаем надолго resolv.conf сохраняется перед изменением
▪️ Автовосстановление (по cron)

if dig "$TEST_DOMAIN" @"$PRIMARY_DNS" > /dev/null && [ -f "$BACKUP" ]; then
    mv "$BACKUP" "$RESOLV"
fi
⚠️ Обратить внимание В системах с systemd-resolved или NetworkManager resolv.conf может перезаписываться; Для серверов лучше использовать resolvectl или override конфигурации; Скрипт требует root. BashTex 📱 #bash

Автоматическая очистка старых бэкапов по количеству копий ▪️ Исходные условия Все бэкапы лежат в одном каталоге; Имена содержат дату или время (важно для сортировки); Нужно оставить, например, 7 последних копий. 🛠 Простой, но надежный скрипт

#!/bin/bash

BACKUP_DIR="/backups"
KEEP=7

cd "$BACKUP_DIR" || exit 1

ls -1t | tail -n +$((KEEP + 1)) | while read -r old_backup; do
    echo "Удаляю старый бэкап: $old_backup"
    rm -rf -- "$old_backup"
done
ls -1t - сортирует файлы по времени изменения (новые сверху) tail -n +$((KEEP + 1)) - выбирает всё после N первых rm -rf -- - безопасно удаляет, даже если имя начинается с -
▪️ Полезные улучшения Проверка без удаления:

ls -1t | tail -n +$((KEEP + 1))
Фильтрация только нужных бэкапов:

ls -1t backup-* | tail -n +$((KEEP + 1))
Логирование:

rm -rf -- "$old_backup" >> /var/log/backup-cleanup.log 2>&1
BashTex 📱 #bash #utils

📘 На Stepik вышел курс — «DevOps-инженер: От основ до продакшена» Уже пишете код или администрируете серверы и хотите перейт
📘 На Stepik вышел курс — «DevOps-инженер: От основ до продакшена» Уже пишете код или администрируете серверы и хотите перейти на следующий уровень? Этот курс поможет уверенно войти в DevOps. • Полный путь от Linux и сетей до Kubernetes: Docker, Git, GitLab CI/CD, Terraform, Ansible, Prometheus и Grafana • Практика на реальных кейсах: настраиваем пайплайн, контейнеризацию и инфраструктуру кодом, выкатываем сервисы • 180+ интерактивных заданий с автопроверкой — конфиги, манифесты прямо в браузере, в любое удобное время • Итоговый pet-project: к финалу курса у вас будет рабочая инфраструктура с контейнерами, CI/CD и мониторингом 🎓 Сертификат по завершении — добавьте его в резюме или профиль LinkedIn 🚀 Прокачайте DevOps с пользой и удовольствием. Начните уже сегодня и получите скидку 25%, которая действительна в течение 48 часов 👉 Пройти курс на Stepik

Одной тайной меньше BashTex 📱 #юмор
Одной тайной меньше BashTex 📱 #юмор

Автоочистка логов по размеру и времени Логи имеют неприятную привычку расти бесконечно. Ниже простой скрипт, который следит за возрастом и размером логов: старые архивирует, слишком большие режет или удаляет. ▪️ Логика логи старше N дней перемещаем в .gz; логи больше X МБ убираем в архив или удаление; все работает без logrotate; 🛠 Скрипт

LOG_DIR="/var/log/myapp"
MAX_DAYS=7
MAX_SIZE_MB=100

find "$LOG_DIR" -type f -name "*.log" | while read -r file; do
  size_mb=$(du -m "$file" | awk '{print $1}')

  # Архивируем старые логи
  if [[ $(find "$file" -mtime +$MAX_DAYS) ]]; then
    gzip -f "$file"
    continue
  fi

  # Архивируем слишком большие
  if (( size_mb > MAX_SIZE_MB )); then
    gzip -c "$file" > "${file}.gz"
    : > "$file"   # обнуляем без удаления
  fi
done
▪️ Что здесь важно find -mtime - контроль по времени du -m - размер в мегабайтах : > file - безопасное обнуление без потери inode gzip -c - архив без удаления исходника BashTex 📱 #bash #utils

Мониторинг логов с уведомлениями Обычный tail -f - это пассивный просмотр. Но его легко превратить в активный мониторинг, который сам уведомит вас о проблеме. Мы будем читать лог в реальном времени, искать по нужному шаблону и отправлять уведомление. Это отлично подойдет на случай, когда ошибку нужно отловить разово и не нужно городить новый пробник в забиксе. ▪️ Простой пример

LOG="/var/log/myapp/error.log"
PATTERN="ERROR|CRITICAL|FATAL"

tail -F "$LOG" | grep --line-buffered -E "$PATTERN" | while read -r line; do
  echo "[$(date)] $line" | mail -s "Ошибка в логе" admin@bashtex.com
done
▪️ Десктоп-уведомление

tail -F "$LOG" | grep --line-buffered "ERROR" | while read -r line; do
  notify-send "Ошибка в логе" "$line"
done
▪️ Полезные детали -F - переживает logrotate и пересоздание файла --line-buffered - мгновенная реакция, без задержек grep -E - несколько шаблонов сразу while read - обработка построчно без потери данных BashTex 📱 #bash #utils

Замена части файла через временный буфер Иногда sed слишком грубый инструмент: нужны условия, состояние, счетчики. В таких случаях проще пройтись по файлу построчно и собрать новый контент вручную. ▪️ Задача Заменить блок между маркерами # BEGIN и # END, не трогая остальной файл. ▪️ Идея читаем файл построчно; отслеживаем, где мы находимся; пишем результат во временный буфер; атомарно подменяем файл; 🛠 Реализация

in_block=0
tmp=$(mktemp)

while IFS= read -r line; do
  case "$line" in
    "# BEGIN"*)
      in_block=1
      echo "$line" >>"$tmp"
      echo "new content line 1" >>"$tmp"
      echo "new content line 2" >>"$tmp"
      ;;
    "# END"*)
      in_block=0
      echo "$line" >>"$tmp"
      ;;
    *)
      (( in_block )) || echo "$line" >>"$tmp"
      ;;
  esac
done < config.conf

mv "$tmp" config.conf
▪️ Что здесь важно IFS= read -r - сохраняет пробелы и \ mktemp - безопасный временный файл mv - атомарная замена (без битых конфигов) BashTex 📱 #bash #utils

Массовое обновление конфигов через шаблоны ▪️ Шаблон конфига configs/app.conf.tpl

server_name=${HOST};
listen=${PORT};
env=${ENV};
max_clients=${MAX_CLIENTS};
▪️ Задаём переменные

export HOST=bashtex.com
export PORT=8080
export ENV=prod
export MAX_CLIENTS=500
▪️ Массовая генерация конфигов

mkdir -p out

for tpl in configs/*.tpl; do
  envsubst < "$tpl" > "out/$(basename "${tpl%.tpl}")"
done
На выходе:

out/app.conf
out/other.conf
...
▪️ Dry-run перед применением

envsubst < configs/app.conf.tpl | diff -u /etc/app/app.conf -
▪️ Применение с бэкапом

for f in out/*.conf; do
  sudo cp -a "/etc/app/$(basename "$f")"{,.bak}
  sudo cp "$f" /etc/app/
done
▪️ Использование: массовая смена портов/доменов автогенерация конфигов при деплое одинаковые шаблоны на разных хостах BashTex 📱 #bash #utils

Зато там точно есть с кем обсудить топ дистрибутивы BashTex 📱 #юмор
Зато там точно есть с кем обсудить топ дистрибутивы BashTex 📱 #юмор

Собрал чат-бота за вечер → заработал 9 000₽ Ничего придумывать не надо. Открыл шаблон → Собрал бота как конструктор → Получил деньги. Сейчас каждый бизнес живёт в онлайне. Всем нужны чат-боты, авторассылки и другие онлайн-сервисы. Но предприниматели сами не будут разбираться в настройке сервисов. Значит тут появляется отличная ниша для заработка. — 9-15 тыс. ₽ за настройку (3–4 часа работы). — до 50 тыс. ₽ в месяц за сопровождение чат-бота и рассылок. Собирается любой чат-бот на конструкторе, где ты просто расставляешь текст клиента по блокам. Как новичку на создании чат-ботов накопить на отдых, машину, квартиру и все хотелки? Начни бесплатное обучение 👉 @other_digital_bot Там ты за пару недель научишься собирать ботов и сможешь получить клиента.

Анализ больших логов за секунды ▪️ Быстрый фильтр по событию

grep "ERROR" app.log
grep читает файл построчно, подходит даже для очень больших логов. ▪️ Извлечение нужных полей Допустим, формат:

2026-01-20 12:01:33 ERROR user=alice ip=10.0.0.5
Берём только IP:

grep "ERROR" app.log | awk '{print $NF}'
▪️ Агрегация и подсчет Топ источников ошибок:

grep "ERROR" app.log \
| awk '{print $NF}' \
| sort \
| uniq -c \
| sort -nr
Результат:

120 10.0.0.5
 87 10.0.0.3
▪️ Группировка по пользователям

grep "ERROR" app.log \
| awk -F'user=' '{print $2}' \
| awk '{print $1}' \
| sort | uniq -c
BashTex 📱 #bash

Проверка подвисших NFS-монтов и их исправление 1️⃣ Находим NFS-монты

mount | grep nfs
И проверяем, жив ли маунт:

mountpoint -q /mnt/nfs && echo OK || echo BROKEN
2️⃣ Проверяем доступность сервера

showmount -e nfs-server
Если команда висит или падает - это означает, что сервер недоступен, маунт мертв. 3️⃣ Аккуратное отключение (без убийства процессов)

umount -l /mnt/nfs
-l (lazy umount) сразу убирает маунт из системы, а реальные дескрипторы закроются, когда процессы отпустят их. 4️⃣ Автовосстановление

mount /mnt/nfs && echo "NFS restored"
Или перезапуск через fstab:

mount -a -t nfs
Или мини-watchdog

check_nfs() {
  mountpoint -q "$1" || return
  timeout 3 ls "$1" >/dev/null || umount -l "$1"
}
BashTex 📱 #bash #utils

Быстрый сбор системной информации одной командой Когда нужно быстро понять, что за система перед тобой, без Ansible и inventory - достаточно одного короткого скрипта. 🛠 Мини-инвентаризация за один запуск

#!/usr/bin/env bash

echo "=== SYSTEM ==="
uname -a

echo -e "\n=== CPU / MEM ==="
free -h

echo -e "\n=== DISK ==="
df -hT | grep -v tmpfs

echo -e "\n=== NETWORK ==="
ip -br addr
Подходит для: первичного осмотра сервера; SSH-подключений к незнакомой машине; логирования состояния перед изменениями.
▪️ Компактный вариант в одну строку

uname -srmo; free -h; df -hT | awk 'NR==1||!/tmpfs/'; ip -br a
Удобно кидать в чат или запускать на десятках хостов по SSH. ▪️ Формат для логов/отчетов

{
  uname -srmo
  free -h
  df -hT
  ip -br a
} > sysinfo.txt
Можно сохранять как снапшот состояния перед деплоем или обновлением. BashTex 📱 #bash

Проверка доступности сервисов с автоперезапуском Иногда нужен не Zabbix, а простейший контроль жив или нет. Для HTTP-сервисов это легко решается связкой curl + systemctl. ▪️ Базовая проверка доступности

curl -sf http://127.0.0.1:8080/health || echo "DOWN"
-s - тихо -f - ошибка, если HTTP ≠ 2xx exit-код ≠ 0 - сервис недоступен ▪️ Автоперезапуск сервиса

SERVICE=myapp
URL=http://127.0.0.1:8080/health

if ! curl -sf --max-time 3 "$URL"; then
  logger "watchdog: $SERVICE is down, restarting"
  systemctl restart "$SERVICE"
fi
--max-time защищает от зависших запросов logger пишет в syslog (удобно для аудита) ▪️ Защита от флаппинга (несколько неудач подряд)

FAILS=/run/myapp.watchdog.fail
MAX=3

if ! curl -sf "$URL"; then
  n=$(($(cat "$FAILS" 2>/dev/null || echo 0)+1))
  echo "$n" > "$FAILS"
  [[ $n -ge $MAX ]] && systemctl restart "$SERVICE"
else
  rm -f "$FAILS"
fi
Рестарт только если сервис падает несколько раз подряд. ▪️ Запуск по cron

*/1 * * * * /usr/local/bin/watchdog.sh
BashTex 📱 #bash #utils

🔧 Для системных администраторов и IT-специалистов! Ищете надежный источник знаний и поддержки? Тогда вам к нам! 📚 Что у нас
🔧 Для системных администраторов и IT-специалистов! Ищете надежный источник знаний и поддержки? Тогда вам к нам! 📚 Что у нас есть: - Книги по Cisco Systems, Mikrotik, VoIP, Linux и Windows Server - Руководства по сетевым технологиям - 📽 Видеоуроки на актуальные темы - 🤝 Поддержка от сообщества Присоединяйтесь к нашему сообществу профессионалов: @sysadmin1

🪞 BashTex 📱 #юмор
🪞 BashTex 📱 #юмор

Живой мониторинг процессов с цветом и сортировкой watch - недооцененный инструмент. Он превращает любую команду в живую панель наблюдения, обновляя вывод каждые N секунд. Если добавить цвет, сортировку и фильтры у вас получается почти мини htop без внешних утилит. ▪️ Базовый пример: отслеживание топ-процессов

watch -n 1 'ps aux --sort=-%cpu | head -20'
-n 1 - обновление каждую секунду --sort=-%cpu - сортировка по нагрузке head -20 - только важные строки
▪️ Цветной вывод внутри watch. Если команда выводит ANSI-цвета, watch их покажет, но нужно включить -c:

watch -c 'ps aux | grep --color=always nginx'
Или:

watch -c 'ps aux --sort=-%mem | head -15'
▪️ Подсветка подозрительных процессов. Например, ищем процессы, использующие много памяти (>10%):

watch -n 1 -c '
  ps aux --sort=-%mem \
    | awk '\''$4>10{print "\033[31m"$0"\033[0m"} $4<=10{print}'\'''
Процессы >10% MEM подсвечиваются красным. ▪️ Отслеживание процессов конкретного пользователя

watch 'ps -u deploy --sort=-%cpu | head'
▪️ Комбинация watch + pgrep. Смотрим, что делает группа процессов по паттерну:

watch 'pgrep -fl python | sort'
▪️ Небольшой дашборд: несколько метрик за раз (через bash -c)

watch -n 2 -c '
  echo "== CPU =="; ps aux --sort=-%cpu | head -5;
  echo ""; 
  echo "== MEM =="; ps aux --sort=-%mem | head -5;
'
BashTex 📱 #bash #utils

Проверка целостности системных пакетов через пакетный менеджер Если есть подозрение на вмешательство в систему: подмену бинарников, изменение конфигов, в таком случае первым делом стоит проверить: файлы пакетов соответствуют тому, что установлено из репозиториев? Linux-дистрибутивы уже умеют делать это штатно. Нужно только правильно спросить. ▪️ RPM-базовые системы (CentOS, RHEL, Rocky, Fedora). Команда:

sudo rpm -Va
Она проверяет все файлы всех пакетов, сверяя: размер хеш права владельца время модификации
Формат вывода:

S.5....T.  /usr/bin/ssh
Где: S - размер отличается 5 - хеш не совпадает T - время модификации изменено
Чтобы увидеть только реальные расхождения, можно отфильтровать шум:

sudo rpm -Va | grep -v '^..c'
..c - это конфиги, которые обычно меняются вручную. ▪️ Debian/Ubuntu: debsums. Если система на DEB-пакетах:

sudo apt install debsums
sudo debsums -s
-s выводит только файлы, чьи MD5-суммы не совпадают с эталоном из репозитория. Проверка конкретного пакета:

sudo debsums -s openssh-server
BashTex 📱 #bash #security