BashTex | Linux
2.53K subscribers
71 photos
12 videos
409 links
Авторский канал для тех, кто хочет глубже погрузиться в мир Linux.

Подойдет для разработчиков, системных администраторов и DevOps

Реклама: @dad_admin
Download Telegram
Само обнаружение

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁5
Почему сервис не стартует?

1️⃣ Быстрая проверка статуса


systemctl status myservice -n 20 --no-pager


Смотрим:

Loaded
Active
ExecStart
последние строки логов


2️⃣ Смотрим реальные ошибки из journal


journalctl -u myservice -xe --no-pager


Частые сообщения:

Permission denied
No such file or directory
Address already in use
Failed to bind
Unit entered failed state


3️⃣ Проверяем unit-файл


systemctl cat myservice


Ошибки часто здесь:

неправильный путь в ExecStart
забыли daemon-reload
лишний User=
отсутствующая рабочая директория


Проверка синтаксиса:


systemd-analyze verify /etc/systemd/system/myservice.service


4️⃣ Типовые причины, которые встречаются чаще всего

🤩 Неверный путь к бинарнику: ExecStart=/usr/bin/app
Файл не существует и сервис не стартует.

🤩 Порт уже занят


ss -lntp | grep 8080


🤩 Неправильные права


ls -l /path/to/app


Нужно проверить владельца и execute-бит.

🤩 Ошибка в конфиге приложения. Попробуй запустить вручную:


sudo -u serviceuser /usr/bin/app


🛠 Небольшой скрипт диагностики


#!/bin/bash
SERVICE="$1"

echo "=== STATUS ==="
systemctl status "$SERVICE" -n 10 --no-pager

echo
echo "=== LAST ERRORS ==="
journalctl -u "$SERVICE" -n 20 --no-pager

echo
echo "=== UNIT FILE ==="
systemctl cat "$SERVICE"

echo
echo "=== PORT CHECK ==="
ss -lntp | grep "$(systemctl show "$SERVICE" -p ExecStart --value | awk '{print $1}')" 2>/dev/null


Запуск:


./diag.sh nginx


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Чеклист для ситуации, когда сервер под нагрузкой

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

1️⃣ CPU: кто жрет процессор


uptime


Смотрим:

Load Average
сравниваем с количеством CPU (nproc)


Если load > количества ядер - это означает, что проблема есть.

Детализация:


top


Смотрим:

%CPU
us / sy / wa
процессы в топе


Если высокий wa, то проблема в IO.

2️⃣ IO: не уперлись ли в диск


iostat -xz 1 3


Смотрим:

%util
await
svctm


Если %util ≈ 100% - диск забит.

Быстрое упрощение:


iotop


Кто активно пишет/читает.

3️⃣ Память: нет ли OOM


free -h


Проверяем:

свободная память
swap


И сразу:


dmesg | grep -i oom


Если есть OOM Killer, то причина найдена.

4️⃣ Сеть: не уперлись ли в соединения


ss -s


Смотрим:

ESTAB
TIME-WAIT
orphaned sockets


И:


iftop


Кто льет трафик.

5️⃣ Процессы: нет ли runaway


ps aux --sort=-%cpu | head
ps aux --sort=-%mem | head


Смотрим:

неожиданные процессы
бесконечные воркеры


6️⃣ Быстрый общий снимок


top -b -n1 | head -20


Будет полезно для фиксации состояния.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥4
Управление выводом

В консоли все выглядит одинаково. Но для системы это два разных потока:

stdout - нормальный вывод (FD 1)
stderr - ошибки (FD 2)

И если их не различать - автоматизация начинает ломаться.

▪️ Что такое stdout и stderr. Пример:


echo "OK"
echo "ERROR" >&2


Первое уйдет в stdout, второе в stderr.

Проверим:


./script.sh >out.log 2>err.log


Теперь:

out.log - нормальный результат
err.log - ошибки

⚠️ Почему это важно

1️⃣ CI/CD пайплайны. В системах вроде GitHub Actions или GitLab CI:

stdout - это лог выполнения
stderr - это ошибка шага

Если приложение пишет все в stdout, то и пайплайн может считать шаг успешным.

2️⃣ Парсинг вывода в скриптах. Типичная ошибка:


result=$(some_command)


Если some_command пишет ошибку в stdout - переменная будет содержать текст ошибки.
Автоматизация съест ее как валидные данные.

3️⃣ Логирование в systemd. В systemd:

stdout - это StandardOutput
stderr - это StandardError

Если сервис пишет ошибки в stdout, мониторинг может их не выделить.

🤩 Типичный анти-паттерн


if curl bashtex.com; then
echo "OK"
fi


Если curl вернет HTTP 500, сообщение об ошибке может уйти в stdout.

🤩 Правильно:


if curl -fsS bashtex.com; then
echo "OK"
else
echo "FAIL" >&2
fi


▪️ Управление потоками.

Раздельная запись

command >out.log 2>err.log


Объединить

command >all.log 2>&1


Игнорировать ошибки

command 2>/dev/null


Поменять местами

command 3>&1 1>&2 2>&3


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Свернуть с этой дорожки уже не получится

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁13🔥1
Сравнение конфигураций сервиса между серверами

Классическая ситуация: на одном сервере все работает. На другом - нет. При этом версии одинаковые, ОС одинаковая, но потом спустя время выясняется: конфиг отличается на одну строку.

😁Задача

Сравнить конфигурации одного сервиса между серверами:

nginx.conf
sshd_config
app.conf

Быстро. Чисто. Без копипасты глазами.


1️⃣ Самый простой способ - diff через SSH


ssh server1 "cat /etc/nginx/nginx.conf" > s1.conf
ssh server2 "cat /etc/nginx/nginx.conf" > s2.conf

diff -u s1.conf s2.conf


Но это неудобно и мусорно.

Лучше сразу:


diff -u \
<(ssh server1 "cat /etc/nginx/nginx.conf") \
<(ssh server2 "cat /etc/nginx/nginx.conf")


Чисто. Без временных файлов.

2️⃣ Игнорировать комментарии и пустые строки. Очень часто различия только в комментариях.


diff -u \
<(ssh s1 "grep -vE '^\s*#|^\s*$' /etc/ssh/sshd_config") \
<(ssh s2 "grep -vE '^\s*#|^\s*$' /etc/ssh/sshd_config")


Теперь сравнивается только реальная логика.

3️⃣ Если это nginx - сравнивать весь effective config. У nginx часто include-файлы.

Правильнее:


ssh s1 "nginx -T" > s1.nginx
ssh s2 "nginx -T" > s2.nginx

diff -u s1.nginx s2.nginx


Так мы сравниваем итоговую конфигурацию.

4️⃣ Проверка sshd. У ssh есть удобная команда:


sshd -T


Она выводит итоговую конфигурацию с учетом defaults. Сравниваем так же через process substitution.

5️⃣ Если серверов много. Массовая проверка:


for host in s1 s2 s3; do
ssh "$host" "sshd -T" | sort > "$host.conf"
done

diff -u s1.conf s2.conf


Сортировка помогает убрать разницу порядка строк.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Отладка bash-скриптов

В bash есть встроенная трассировка, и она может быть эффективнее любого printf-дебага.

1️⃣ Включаем трассировку


set -x


Теперь каждая команда будет выводиться перед выполнением:


+ var=10
+ echo 10


Отключить:


set +x


Полезно включать только на проблемном участке.

2️⃣ Отладка всего скрипта. Можно запустить сразу так:


bash -x script.sh


Или добавить в начало:


#!/bin/bash
set -x


3️⃣ Сделать трассировку читаемой. По умолчанию вывод начинается с +. Это скучно. Можно добавить больше контекста:


export PS4='+ $(date "+%H:%M:%S") ${BASH_SOURCE}:${LINENO}: '


Теперь вывод будет выглядеть так:


+ 14:32:10 script.sh:12: var=10


Здесь видно: время, файл и номер строки Для сложных скриптов - это крайне полезно.

4️⃣ Отдельный лог отладки. Чтобы не засорять stdout:


exec 3>/tmp/debug.log
BASH_XTRACEFD=3
set -x


Теперь трассировка уйдет в /tmp/debug.log, а основной вывод останется чистым. Это особенно важно для автоматизации и CI.

5️⃣ Отладка переменных. Полезные режимы:


set -u # ошибка при использовании unset переменной
set -e # выход при ошибке
set -o pipefail # ловим ошибки в пайпах


Продвинутый вариант:


set -euxo pipefail


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥3
Генерация временных файлов

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


TMP="/tmp/script.$RANDOM"


И вроде все ок, но на деле это один из самых старых и самых недооцененных багов в bash.

▪️ Почему /tmp/file.$RANDOM - это плохая идея
1️⃣ Коллизии.

$RANDOM - это число от 0 до 32767. При параллельном запуске скриптов совпадения реальны.

2️⃣ Race condition. Ты:


echo "data" > /tmp/file.$RANDOM


А злоумышленник заранее создал симлинк с таким именем и твой скрипт перезапишет чужой файл. Это классическая symlink attack.

3️⃣ Неправильные права. Файл создается с текущим umask. Это может быть не то, что ты ожидал.

▪️ Правильный способ - mktemp


TMP=$(mktemp)


Результат:


/tmp/tmp.ABCd93kL


Что делает mktemp:

генерирует криптографически безопасное имя
создаёт файл атомарно
выставляет права 600
исключает race condition


▪️ Создание временной директории


TMP_DIR=$(mktemp -d)


▪️ Правильная очистка. Всегда следует добавлять cleanup:


TMP=$(mktemp)

cleanup() {
rm -f "$TMP"
}
trap cleanup EXIT


Теперь файл удалится даже при ошибке или Ctrl+C.

▪️ Когда нужно имя с префиксом


mktemp /tmp/myscript.XXXXXX


Или:


mktemp -d /tmp/myscript.XXXXXX


XXXXXX обязательно - это шаблон.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Почему sleep - это костыль?

Очень часто используют такую конструкцию:


curl https://api.bashtex.com || sleep 5 && curl https://api.bashtex.com


Или ещё хуже: в цикле с фиксированной паузой.

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

Правильный подход - retry с exponential backoff.

▪️ Почему sleep 5 - это плохая стратегия.

Представим: API лежит 2 минуты. 100 серверов начинают делать: запрос -> sleep 5 -> запрос -> sleep 5 → …
Ты получаешь синхронную атаку на уже мертвый сервис.

Exponential backoff делает паузы все длиннее: 1s -> 2s -> 4s -> 8s -> 16s -> ...
Это: снижает нагрузку, дает сервису восстановиться, уменьшает каскадные падения

🛠 Базовая retry-обертка


retry() {
local max_attempts=$1
shift

local attempt=1
local delay=1

while true; do
"$@" && return 0

if (( attempt >= max_attempts )); then
echo "Команда не удалась после $attempt попыток"
return 1
fi

echo "Попытка $attempt неудачна. Повтор через $delay сек."
sleep "$delay"

attempt=$(( attempt + 1 ))
delay=$(( delay * 2 ))
done
}


▪️ Использование:


retry 5 curl -fsS https://api.bashtex.com


▪️ Что здесь происходит

"$@" - передаем любую команду;
выходной код управляет retry;
задержка удваивается;
максимум попыток ограничен.

▪️ Когда retry вреден

при логических ошибках (401, 403);
если операция не идемпотентна;
если сервис возвращает fatal error.

Retry должен применяться к временным ошибкам, а не ко всем подряд.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Профилирование bash-скрипта

Большинство bash-скриптов медленные не потому что bash плохой, а потому что внутри: лишние grep | awk | sed, десятки subshell, сетевые вызовы без таймаутов и циклы по 100k строк

И пока не измерил - не оптимизируешь.

1️⃣ Базовый уровень - time. Самое простое:


time ./script.sh


Вывод:


real 0m3.421s
user 0m0.212s
sys 0m0.084s


Что важно:

real - общее время (включая ожидание сети, IO)
user - CPU в user space
sys - системные вызовы


Если real > user + sys - это значит, что скрипт ждет (сеть, диск, sleep).
Если user большой - это значит много вычислений.

2️⃣ Профилирование построчно через DEBUG trap. Настоящая магия начинается здесь.


#!/usr/bin/env bash

PS4='+ $(date "+%s.%N") '
exec 3>&2
BASH_XTRACEFD=3
set -x


Но это просто трассировка. Чтобы измерять время между строками:


#!/usr/bin/env bash

last_time=$(date +%s%N)

trap '
now=$(date +%s%N)
diff=$(( (now - last_time) / 1000000 ))
echo "${diff} ms → $BASH_COMMAND"
last_time=$now
' DEBUG


Теперь перед каждой командой будет вывод:


2 ms → var=$(cat file)
153 ms → curl https://api
1 ms → echo done


И сразу видно: где реальная задержка, какой вызов тормозит и сколько стоит subshell

⚠️ Важно

trap DEBUG вызывается перед каждой командой, включая: внутренние, подстановки и циклы.

На больших скриптах лог будет огромный.

▪️ Мини-профилировщик функции. Если нужно измерить только конкретный блок:


measure() {
local start=$(date +%s%N)
"$@"
local end=$(date +%s%N)
echo "Функция заняла $(( (end - start)/1000000 )) ms"
}


Использование:


measure heavy_function


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Автоматический failover при недоступности mount-точки

Неприятная ситуация когда mount вроде есть, но по факту хранилище уже умерло. NFS отвалился. iSCSI завис. Ceph не отвечает. Сервис продолжает писать… в никуда.

Решение - автоматическая логика: Проверка -> попытка remount -> переключение на fallback.

▪️ Логика failover

Проверяем, что mount существует;
Проверяем доступность записи;
Если ошибка, то пробуем remount;
Если не помогло - переключаемся на fallback.

🛠 Пример скрипта


#!/usr/bin/env bash

MOUNT_POINT="/data"
FALLBACK="/data_local"
TEST_FILE="$MOUNT_POINT/.healthcheck"

log() {
echo "$(date '+%F %T') | $1"
}

check_mount() {
mountpoint -q "$MOUNT_POINT" || return 1
timeout 3 touch "$TEST_FILE" 2>/dev/null || return 1
rm -f "$TEST_FILE"
}

remount() {
log "Попытка remount..."
mount -o remount "$MOUNT_POINT"
}

switch_to_fallback() {
log "Переключение на fallback $FALLBACK"
umount -l "$MOUNT_POINT"
mount --bind "$FALLBACK" "$MOUNT_POINT"
}

main() {
if check_mount; then
log "Mount работает нормально"
exit 0
fi

log "Mount недоступен"

remount && sleep 2

if check_mount; then
log "Remount помог"
exit 0
fi

switch_to_fallback
}

main


▪️ Что здесь важно

1. timeout - если NFS завис, без timeout скрипт повиснет навсегда.
2. mountpoint -q - Проверяет именно mount, а не просто директорию.
3. umount -l - lazy umount - полезно, если есть залипшие процессы.

▪️ Как запускать правильно

Лучше всего: systemd timer или healthcheck внутри сервиса или отдельный watchdog unit

⚠️ Нюансы

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

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8
Не все так просто, кожаный

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁12
Sync tricks: инкременты, hard links и бэкапы

Все знают про rsync, но не все используют его на 100%. Сегодня разберем три мощных приема: инкрементальные бэкапы, hard links для экономии места и атомарная схема снапшотов

1️⃣ Инкрементальный sync. База:


rsync -a --delete /data/ /backup/current/


Что происходит:

-a - сохраняет права, владельца, время
--delete - удаляет лишнее в приемнике

Это зеркало. Но это не история. Каждый запуск перезаписывает прошлый бэкап.

2️⃣ Настоящие снапшоты через hard links. Допустим, структура такая:


/backup/
├── 2026-03-29/
├── 2026-03-30/
└── 2026-03-31/


Команда:


TODAY=$(date +%F)
YESTERDAY=$(date -d "yesterday" +%F)

rsync -a --delete \
--link-dest=/backup/$YESTERDAY \
/data/ /backup/$TODAY/


Что происходит:

изменённые файлы - копируются
неизмененные - создаются как hard link
места занимает почти как один бэкап

Что тут необычного?

Hard link - это не копия файла. Это второе имя для того же inode. Проверка:


ls -li file1 file2


Одинаковый inode - это один и тот же файл.

Удаляешь снапшот 29-го числа и файл не удалится, если он есть в 30-м.

Здесь же и начинается экономия места. Если данные почти не меняются: 30 снапшотов могут занимать +5–10% к объему, вместо ×30 бэкапов. Это почти как ZFS snapshots, но работает на обычном ext4.

3️⃣ Атомарная схема без битых бэкапов. Никогда не пиши прямо в конечную папку.

Правильно:


rsync -a --delete \
--link-dest=/backup/$YESTERDAY \
/data/ /backup/.tmp-$TODAY/ &&
mv /backup/.tmp-$TODAY /backup/$TODAY


Теперь:

если rsync упал - снапшот не появится
всегда либо полный, либо отсутствует

4️⃣ Ротация снапшотов. Храним 14 дней:


find /backup -maxdepth 1 -type d -mtime +14 -exec rm -rf {} \;


(Осторожно с путями.)

🛠 Мини-скрипт


#!/usr/bin/env bash
set -euo pipefail

SRC="/data"
DST="/backup"
TODAY=$(date +%F)
YESTERDAY=$(ls -1 $DST | sort | tail -n 1)

rsync -a --delete \
${YESTERDAY:+--link-dest=$DST/$YESTERDAY} \
"$SRC/" "$DST/.tmp-$TODAY/"

mv "$DST/.tmp-$TODAY" "$DST/$TODAY"


Первый запуск - обычная копия.
Все следующие - инкременты.

BashTex 📱 #bash #backup
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Почему cron не сработал

Каждый админ хотя бы раз слышал: Cron не отработал.
Но, спойлер: в 90% случаев cron работает. Не работает: окружение, путь или логика скрипта.

1️⃣ Неправильный PATH. Cron запускается с минимальным окружением. То, что работает в shell:


myscript.sh


В cron может не найти: command not found

Проверка:


echo $PATH


Решение:


PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin


Или использовать абсолютные пути:


/usr/bin/rsync
/usr/bin/docker


2️⃣ Не тот пользователь. Есть:


crontab -e


И есть:


sudo crontab -e


Это два разных crontab.

Проверка:


crontab -l
sudo crontab -l


Иногда задача просто стоит не там.

3️⃣ Нет прав на файл. Скрипт есть. Но:


chmod +x script.sh


забыли. Или владелец не тот.

4️⃣ Неправильный shebang. Если в начале:


#!/bin/bash


А на системе bash лежит в:


/usr/bin/bash


Cron молча свалится. Проверка:


which bash


Лучший вариант:


#!/usr/bin/env bash


5️⃣ Нет логирования и кажется, не сработал Если вывод не перенаправлен, ты его не увидишь. Правильно:


0 3 * * * /path/script.sh >> /var/log/script.log 2>&1


Без этого ты гадаешь.

6️⃣ Разница окружения. Cron не знает:

твоих alias
твоих переменных
твоего virtualenv
твоего nvm

Если работает вручную, но не в cron - почти всегда проблема в ENV.

Debug-метод:


env > /tmp/cron_env.txt


7️⃣ Скрипт падает внутри. Cron сработал. Но внутри:


rm -rf "$DIR"


где $DIR пустой.

Без:


set -euo pipefail


ошибка могла остаться незамеченной.

8️⃣ Cron вообще не запущен. Редко, но бывает. Проверка:


systemctl status cron
# или
systemctl status crond


BashTex 📱 #cron
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11
Спалили

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁11🔥1
Работа с дескрипторами файлов

В linux все - это файл. И каждый процесс работает с файловыми дескрипторами:

0 - stdin
1 - stdout
2 - stderr
3+ - любые дополнительные

Понимание этого - ключ к нормальной автоматизации.

▪️ Базовые перенаправления


command >out.log # stdout
command 2>err.log # stderr
command >all.log 2>&1 # объединить


2>&1 значит: направь stderr туда же, куда сейчас смотрит stdout.

⚠️ Порядок важен: command 2>&1 >file - НЕ то же самое.

▪️ Dup (дублирование дескрипторов). Можно создать свой поток:


exec 3>debug.log
echo "debug" >&3


Теперь 3 пишет в debug.log.

Это удобно, если нужно:

отделить debug-лог от основного вывода
не засорять stdout
вести параллельный лог

▪️ Временное перенаправление


{
echo "только в файл"
} >file.txt


Или:


exec >all_output.log 2>&1


Теперь весь скрипт пишет в лог.

▪️ Закрытие дескриптора. Иногда нужно закрыть поток:


exec 3>&-


Это освобождает дескриптор.
Полезно при работе с сокетами, FIFO и временными логами.

▪️ Практический кейс. Раздельный лог и чистый stdout:


exec 3>debug.log
BASH_XTRACEFD=3
set -x


Трассировка уйдет в файл, а stdout останется чистым для пайплайна.

BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Контроль превышения лимитов ulimit у сервисов

Сервис падает без причины, но в логах странные ошибки:

Too many open files
Resource temporarily unavailable
fork: retry
cannot allocate memory


Очень часто это не баг. Это лимиты ulimit.

▪️ Какие лимиты критичны
1️⃣ nofile - открытые файлы. Сколько файловых дескрипторов может открыть процесс.

Проверка:


ulimit -n


Или для конкретного процесса:


cat /proc/<PID>/limits | grep "Max open files"


Если видишь 1024, то для прод-сервиса это почти всегда мало.

2️⃣ nproc - количество процессов. Ограничение на число процессов пользователя.

Проверка:


ulimit -u


Или:


cat /proc/<PID>/limits | grep "Max processes"


Если приложение активно форкает воркеры - лимит может убить его.

▪️ Почему это сложно заметить

сервис стартует нормально
падает только под нагрузкой
в логах нет прямого указания на лимит
systemd может перезапускать бесконечно

▪️ Проверка лимитов у systemd-сервиса


systemctl show myservice | grep -E 'LimitNOFILE|LimitNPROC'


Если пусто, то используются дефолтные значения системы.

▪️ Как исправить. Создать override:


systemctl edit myservice


Добавить:


[Service]
LimitNOFILE=65535
LimitNPROC=4096


Перезагрузить:


systemctl daemon-reload
systemctl restart myservice


▪️ Быстрая диагностика падений. Если сервис падает под нагрузкой:


/proc/<PID>/limits


Посмотреть количество открытых файлов:


ls /proc/<PID>/fd | wc -l


Проверить количество процессов пользователя:


ps -u username | wc -l


BashTex 📱 #bash #check
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Современный мониторинг ресурсов

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

▪️ Что показывает btop. В одном окне можно увидеть:

загрузку CPU по ядрам
использование RAM и swap
дисковую активность
сетевой трафик
список процессов с сортировкой

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

▪️ Установка


sudo apt install btop # Ubuntu / Debian
sudo dnf install btop # RHEL / CentOS / Fedora
sudo pacman -S btop # Arch


▪️ Запуск:


btop


🤩 Что делает его удобным

Интерактивный список процессов

Можно:

сортировать по CPU / RAM
убивать процессы
фильтровать список

▪️ Клавиши:

F9 - kill process
F6 - сортировка
F - поиск процесса

▪️ Мониторинг сети. btop показывает:

входящий / исходящий трафик
скорость сети
активность интерфейсов

Это удобно, когда нужно быстро понять куда уходит трафик.

▪️ Наглядная нагрузка CPU. В отличие от top, здесь видно:

загрузку каждого ядра
историю нагрузки
spikes CPU

Очень полезно при диагностике перегрузки сервера.

▪️ Полезные настройки

Открыть настройки: ESC

Можно изменить:

тему интерфейса
частоту обновления
отображаемые графики
сетевые интерфейсы

Конфиг хранится в:


~/.config/btop/btop.conf


BashTex 📱 #linux #monitoring
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6👍3
Проверка, какие сервисы стартуют дольше всего

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

▪️ Смотрим самые медленные сервисы. Самая полезная команда:


systemd-analyze blame


Пример вывода:


8.532s docker.service
4.921s networkd-wait-online.service
3.102s postgresql.service
1.876s nginx.service


Список уже отсортирован по времени запуска.

Что это значит:

docker.service запускался 8.5 секунд
networkd-wait-online.service ждал сеть почти 5 секунд

Именно такие сервисы чаще всего замедляют загрузку.

▪️ Смотрим цепочку зависимостей. Иногда сервис запускается быстро, но ждет другой сервис. Проверить можно так:


systemd-analyze critical-chain


Пример:


graphical.target
└─docker.service
└─network-online.target
└─systemd-networkd-wait-online.service


Это показывает кто кого блокирует при загрузке.

▪️ Общая статистика загрузки. Полезная команда:


systemd-analyze


Пример:


Startup finished in 3.112s (kernel)
+ 9.842s (userspace)


Здесь видно:

время загрузки ядра
время загрузки systemd сервисов

▪️Частые причины медленной загрузки. Чаще всего тормозят:

networkd-wait-online.service
docker.service
snapd.service
базы данных
storage-сервисы

Иногда сервис ждет ресурс, который ему не нужен.

BashTex 📱 #linux #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Нет времени объяснять, накатывай Linux

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7🗿1
Использование /dev/null правильно

/dev/null - это специальное устройство в linux, которое принимает любые данные и просто их выбрасывает. Часто используется, когда нужно убрать лишний вывод команд.

▪️ Отключаем stdout. Если команда выводит много информации:


ls /tmp > /dev/null


Теперь stdout (fd 1) будет игнорироваться.

▪️ Отключаем только ошибки. Если нужно скрыть stderr (fd 2):


ls /no/such/file 2> /dev/null


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

▪️ Полное подавление вывода. Иногда нужно убрать все:


command > /dev/null 2>&1


Что происходит:

stdout в /dev/null и stderr туда же

▪️ Пример:


curl -s https://bashtex.com > /dev/null 2>&1


Команда выполняется тихо.

▪️ Проверка команды без мусора. Полезный паттерн:


command -v docker > /dev/null 2>&1


Проверяем наличие команды:


if command -v docker > /dev/null 2>&1; then
echo "Docker установлен"
fi


🤩 Частая ошибка. Некоторые пишут:


command 2>&1 > /dev/null


Это не то же самое. Правильный порядок:


command > /dev/null 2>&1


Потому что редиректы выполняются слева направо.

▪️ Практические кейсы. Проверка файла


test -f file.txt > /dev/null 2>&1


Проверка сервиса


systemctl is-active nginx > /dev/null


Проверка сети


ping -c1 google.com > /dev/null 2>&1


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10