BashTex | Linux – Telegram
BashTex | Linux
2.62K subscribers
52 photos
10 videos
320 links
Авторский канал для тех, кто хочет глубже погрузиться в мир Linux.

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

Реклама: @dad_admin
Download Telegram
Отслеживание активности пользователей

Linux хранит всю историю входов в три системные базы:

lastlog - последний логин каждого пользователя
utmp - текущие активные сессии
wtmp - история всех логинов/логаутов

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

1️⃣ Последние входы всех пользователей (lastlog). Показать, кто реально входит в систему:


lastlog | grep -v "Never logged in"


Фильтр подозрительно старых аккаунтов:


lastlog | awk '$4 ~ /Jan|Feb|Mar|Apr/ && $NF != "**Never**"'


2️⃣ Активные сессии прямо сейчас


who


С IP, временем и TTY:


who --ips


Выделение пользователей с нестандартных подсетей:


who --ips | awk '$5 !~ /^10\.|^192\.168\./'


3️⃣ История всех входов/выходов


last -F


Кто заходил чаще всего:


last | awk '{print $1}' | sort | uniq -c | sort -nr | head


Только удаленные логины:


last | grep -E "pts/[0-9]"


4️⃣ Комбинированный отчет


echo "[ACTIVE SESSIONS]"; who --ips
echo "[LAST LOGINS]"; lastlog | grep -v "Never"
echo "[TOP USERS]"; last | awk '{print $1}' | sort | uniq -c | sort -nr | head


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
Обработка SSH-команд через connection pooling

Если вам нужно выполнить десятки или сотни SSH-команд подряд, стандартный подход ssh host cmd превращается в ад: каждый вызов открывает новое TCP-соединение, делает handshake, обмен ключами, проверку known_hosts и все это ради одной короткой команды. Но SSH умеет работать совершенно иначе, через multiplexing. Это когда одно физическое SSH-соединение становится трубой для десятков логических каналов. Команды выполняются без задержек, почти как локальные.

▪️ Включаем connection pooling. Создаем master-socket:


ssh -M -S /tmp/ssh-sock-%r@%h:%p user@server


-M - включить master-режим,
-S - путь до сокета.

Теперь вторичные команды идут через master:


ssh -S /tmp/ssh-sock-%r@%h:%p user@server "hostname"
ssh -S /tmp/ssh-sock-%r@%h:%p user@server "uptime"
ssh -S /tmp/ssh-sock-%r@%h:%p user@server "df -h"


Все эти вызовы выполняются почти мгновенно.

▪️ Автоматизация: ~/.ssh/config. Чтобы не писать все вручную:


Host *
ControlMaster auto
ControlPath ~/.ssh/cm-%r@%h:%p
ControlPersist 10m


Теперь SSH сам создает и держит мастер-сессию 10 минут после последней команды.

▪️ Массовый запуск команд по списку


#!/bin/bash

for host in $(cat hosts.txt); do
ssh "$host" "uptime" &
done

wait


▪️ Завершение мастер-сессии


ssh -O exit -S ~/.ssh/cm-user@host:22 host


BashTex 📱 #bash #utils
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2
Работа с архивами без распаковки

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

1️⃣ Просмотр содержимого


tar -tf archive.tar.gz # tar

unzip -l archive.zip # zip

7z l archive.7z # 7z


2️⃣ Grep внутри архива (без извлечения)

tar позволяет выводить файлы в stdout, можно grep через pipe:


tar -xOf archive.tar.gz path/to/file.txt | grep "ERROR"


Или искать по всем файлам:


tar -xOf archive.tar.gz $(tar -tf archive.tar.gz) | grep "pattern"


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


unzip -p archive.zip logs/app.log | grep "WARN"


7z (лучший вариант для grep по всем файлам)


7z x -so archive.7z | grep "pattern"


Или по конкретному файлу:


7z x archive.7z -so -i!*.log | grep "ERROR"


3️⃣ Поиск файла по части имени


7z l archive.7z | grep "\.conf"
tar -tf backup.tar | grep "nginx"
unzip -l logs.zip | grep ".log"


BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Автоматическая синхронизация каталогов по списку хостов

Когда один и тот же каталог нужно поддерживать в актуальном состоянии на нескольких серверах, самый простой инструмент: rsync. Но руками гонять его по каждому хосту - это боль. Можно написать маленький скрипт, который делает это автоматически.

▪️ Простой пример: синхронизация по списку хостов. Допустим, есть файл hosts.txt:


srv1
srv2
srv3


🛠 Скрипт:


#!/usr/bin/env bash

SRC="/opt/app/"
DEST="/opt/app/"
HOSTS="hosts.txt"

for host in $(cat "$HOSTS"); do
echo "[*] Sync to $host..."
rsync -az --delete "$SRC" "$host:$DEST"
done


Скрипт:

Синхронизирует каталог на каждый хост;
Удаляет лишние файлы (--delete);
Передает только изменения (-a + -z);
Работает со сколько угодно хостами записанными в hosts.txt

▪️ Плюс: можно добавить контроль доступности


ping -c1 -W1 "$host" >/dev/null || {
echo "$host недоступен, пропускаю"
continue
}


BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Когда на новый год попросил побольше ОП, но почему-то теперь вместо винды стоит линукс 😁

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
😁11👍4🗿1
Проверка слабых паролей пользователей

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

▪️ Что можно проверить

Возраст пароля, если пароль не меняли 500+ дней - тревожный знак;
Минимальный и максимальный срок действия (политики PASS_MAX_DAYS);
Пользователи с never expires, часто признак устаревших или слабозащищенных аккаунтов;
Аккаунты с неограниченным логином (chage -l).

🛠 Скрипт


#!/usr/bin/env bash

echo "user,last_change,max_days,warning,expires"

for user in $(cut -d: -f1 /etc/shadow); do
info=$(chage -l "$user" 2>/dev/null)

last_change=$(echo "$info" | grep "Last password change" | cut -d: -f2 | xargs)
max_days=$(echo "$info" | grep "Maximum" | awk '{print $4}')
warning=$(echo "$info" | grep "Warning" | awk '{print $4}')
expires=$(echo "$info" | grep "Password expires" | cut -d: -f2 | xargs)

echo "$user,$last_change,$max_days,$warning,$expires"
done


▪️ Чтение результатов

max_days = 99999 - это значит, что политика отсутствует, пароль вечный
expires = never означает, что аккаунт может быть заброшенным или небезопасным
last_change слишком старый - стоит пройтись по пользователям и потребовать смены

BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Как находить зависшие задачи запущенные cron

Зависшие cron-задачи - это классика: скрипт повис в I/O, процесс ждет лок, завис ssh и сервер уже не делает регулярные бэкапы, не чистит кеши и не обновляет индексы. Но поймать такие случаи можно и нужно, я расскажу про самый простой способ: cron запускает процессы с PPID = PID cron’а или запускает их в окружении cron. Мы можем искать процессы, запущенные с COMMAND и PPID, и проверять их время жизни.

🛠 Скрипт


#!/usr/bin/env bash

# Максимальное время выполнения задачи (в секундах)
MAX=1800 # 30 минут

now=$(date +%s)

# Ищем процессы, которые запустил cron
ps -eo pid,ppid,etimes,cmd | grep -v grep | while read pid ppid et cmd; do
# ppid == 1 и команды в /etc/cron* — частый кейс
if [[ "$ppid" -eq 1 && "$cmd" == *cron* ]]; then
continue
fi

# Задачи cron обычно запускаются как sh -c "..."
if [[ "$cmd" == *"/etc/cron"* || "$cmd" == *"CRON"* ]]; then
if (( et > MAX )); then
echo "Зависшая задача: PID=$pid, работает уже ${et}s"
fi
fi
done


▪️ Настройка

Поставьте MAX под вашу норму времени выполнения задач.
Добавьте скрипт в /etc/cron.hourly - будете получать регулярный отчет.

BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Массовое переименование файлов по шаблону

▪️ Вариант 1: rename. Если нужно заменить часть имени:


# Заменить "old" на "new" во всех именах
rename 's/old/new/' *.txt


Удалить префикс:


rename 's/^prefix_//' *.log


Добавить суффикс перед расширением:


rename 's/\.jpg$/_edited.jpg/' *.jpg


▪️ Вариант 2: sed + цикл. Когда шаблон сложный или нужно сгенерировать новое имя:


for f in *.mp4; do
new=$(echo "$f" | sed 's/episode_/ep-/; s/_final//')
mv "$f" "$new"
done


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

▪️ Вариант 3: Bash expansion. Если у файлов есть общий номер или маска:


# Добавить нумерацию
n=1
for f in *.png; do
mv "$f" "img_$(printf "%03d" $n).png"
((n++))
done


Переименование 01 в 001:


for f in *.txt; do
mv "$f" "$(printf "%03d".txt "${f%.txt}")"
done


⚠️ Совет: Перед mv всегда смотрите, что получится:


for f in *.txt; do
echo mv "$f" "new-$f"
done


Если вывод выглядит правильно, то можно убирать echo.

BashTex 📱 #bash
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Проверка целостности системных пакетов через пакетный менеджер

Если есть подозрение на вмешательство в систему: подмену бинарников, изменение конфигов, в таком случае первым делом стоит проверить: файлы пакетов соответствуют тому, что установлено из репозиториев?

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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9🔥2
Живой мониторинг процессов с цветом и сортировкой

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
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍1
Please open Telegram to view this post
VIEW IN TELEGRAM
😁15
🔧 Для системных администраторов и IT-специалистов!

Ищете надежный источник знаний и поддержки? Тогда вам к нам!

📚 Что у нас есть:
- Книги по Cisco Systems, Mikrotik, VoIP, Linux и Windows Server
- Руководства по сетевым технологиям
- 📽 Видеоуроки на актуальные темы
- 🤝 Поддержка от сообщества

Присоединяйтесь к нашему сообществу профессионалов: @sysadmin1
🔥1
Проверка доступности сервисов с автоперезапуском

Иногда нужен не 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Быстрый сбор системной информации одной командой

Когда нужно быстро понять, что за система перед тобой, без 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Проверка подвисших 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9
Анализ больших логов за секунды

▪️ Быстрый фильтр по событию


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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Зато там точно есть с кем обсудить топ дистрибутивы

BashTex 📱 #юмор
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9😁4
Массовое обновление конфигов через шаблоны

▪️ Шаблон конфига

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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
Замена части файла через временный буфер

Иногда 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3