Please open Telegram to view this post
VIEW IN TELEGRAM
😁14
Сбор данных с нескольких серверов
Конструкция позволяет сравнивать состояние двух (или нескольких) машин без временных файлов, параллельно и максимально быстро.
Process substitution создает виртуальные файлы, в которые пишется вывод команд. SSH-запросы выполняются параллельно, а diff думает, что сравнивает два обычных файла:
▪️ Лучшие практические примеры
▪️ Сравнение пакетов
▪️ Конфиги (sshd_config)
▪️ Сетевые соединения
▪️ Docker-контейнеры
▪️ Мини-функция
Использование:
BashTex📱 #bash #utils
<(ssh host1 cmd) vs <(ssh host2 cmd)
Конструкция позволяет сравнивать состояние двух (или нескольких) машин без временных файлов, параллельно и максимально быстро.
Process substitution создает виртуальные файлы, в которые пишется вывод команд. SSH-запросы выполняются параллельно, а diff думает, что сравнивает два обычных файла:
diff <(ssh h1 cmd) <(ssh h2 cmd)
diff <(ssh h1 "dpkg -l | sort") \
<(ssh h2 "dpkg -l | sort")
diff -u <(ssh h1 "grep -v '^#' /etc/ssh/sshd_config") \
<(ssh h2 "grep -v '^#' /etc/ssh/sshd_config")
diff <(ssh h1 "ss -tuna | sort") \
<(ssh h2 "ss -tuna | sort")
diff <(ssh h1 "docker ps --format '{{.Names}} {{.Image}}' | sort") \
<(ssh h2 "docker ps --format '{{.Names}} {{.Image}}' | sort")
compare_hosts() {
diff <(ssh "$1" "$3") <(ssh "$2" "$3")
}
Использование:
compare_hosts node1 node2 "df -h"
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12
Сравнение authorized_keys между серверами
Когда в кластере несколько серверов, важно, чтобы доступ имели одни и те же пользователи с одинаковыми ключами. Несогласованность в authorized_keys будет частой точка входа для проблем.
▪️ Базовый прием: сравнение двух серверов
Сразу видно какие ключи есть только на h1 и какие есть только на h2. Строки отличаются полностью, поэтому легко понять лишние.
▪️ Сравнение директорий для всех пользователей
Использование:
▪️ Мультисерверная проверка списка хостов
Покажет отличия между эталоном и всеми остальными.
▪️ Поиск лишних ключей
Покажет ключи, присутствующие только на h1.
BashTex📱 #bash #utils
Когда в кластере несколько серверов, важно, чтобы доступ имели одни и те же пользователи с одинаковыми ключами. Несогласованность в authorized_keys будет частой точка входа для проблем.
diff <(ssh h1 "sort ~/.ssh/authorized_keys") \
<(ssh h2 "sort ~/.ssh/authorized_keys")
Сразу видно какие ключи есть только на h1 и какие есть только на h2. Строки отличаются полностью, поэтому легко понять лишние.
compare_keys() {
user="$1"
diff <(ssh "$2" "sort /home/$user/.ssh/authorized_keys 2>/dev/null") \
<(ssh "$3" "sort /home/$user/.ssh/authorized_keys 2>/dev/null")
}
Использование:
compare_keys deploy h1 h2
compare_keys admin h1 h2
hosts=(h1 h2 h3)
base="h1"
for h in "${hosts[@]:1}"; do
echo "=== $base vs $h ==="
diff <(ssh "$base" "sort ~/.ssh/authorized_keys") \
<(ssh "$h" "sort ~/.ssh/authorized_keys")
done
Покажет отличия между эталоном и всеми остальными.
ssh h1 "sort ~/.ssh/authorized_keys" \
| grep -vFf <(ssh h2 "sort ~/.ssh/authorized_keys")
Покажет ключи, присутствующие только на h1.
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Сложные пайпы в bash
Иногда нужно одновременно: подавать данные в программу, анализировать ее вывод, логировать поток, фильтровать часть данных и все это без временных файлов. Такое легко делается через tee + process substitution.
▪️ Базовый шаблон
и при этом нет temp-файлов, все идёт по fd
▪️ Пример 1: анализ, логирование и фильтрация сразу. Извлекаем ошибки в отдельный файл, а общий вывод обрабатываем:
▪️ Пример 2: split-поток для алертов и статистики
▪️ Пример 3: читаем и пишем в интерактивный процесс. Двунаправленная работа с программой:
Работает как мини-оркестратор для интерактивного ввода/вывода.
BashTex📱 #bash #utils
Иногда нужно одновременно: подавать данные в программу, анализировать ее вывод, логировать поток, фильтровать часть данных и все это без временных файлов. Такое легко делается через tee + process substitution.
cat input.log \
| cmd \
| tee >(grep "ERROR" > errors.log) \
| awk '{print $1, $3}'
cmd принимает stdin от cat;tee дублирует поток: в файл-поток >(grep ...) и дальше в awk;grep работает параллельно, не мешая основному пайпу;и при этом нет temp-файлов, все идёт по fd
journalctl -u nginx \
| tee >(grep 500 >500.log) \
| awk '/request/ {print $NF}'
tail -F app.log \
| tee >(grep CRITICAL | notify-send "ALERT!") \
| awk '{count[$5]++} END {for (i in count) print i, count[i]}'
coproc APP { cmd --interactive; }
echo "status" >&"${APP[1]}"
cat <&"${APP[0]}" \
| tee >(grep ALERT >alerts.log) \
| awk '{print "OUT:", $0}'
Работает как мини-оркестратор для интерактивного ввода/вывода.
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Использование socat как универсального канала между скриптами
▪️ Bash через UNIX-сокет. Мини-IPC без tmp-файлов и named pipes:
Сервер:
Клиент:
Отлично подходит для локальных API между скриптами.
2️⃣ Передача данных между серверами (TCP)
Сервер:
Клиент:
Можно в реальном времени стримить логи или метрики.
3️⃣ Замена сложных пайпов. Напрямую соединяем процессы, даже если они не умеют работать с stdin/stdout:
Аналог cmd1 | cmd2, но без ограничений пайпа (например, поддержка bidirectional).
4️⃣ Двунаправленный канал в скрипте. Например, общение с интерактивным сервисом:
Можно строить собственные протоколы поверх TCP.
5️⃣ Быстрый импровизированный RPC
Сервер:
Клиент:
BashTex📱 #bash #utils
socat позволяет связать любой источник данных с любым приемником. Bash-скрипты с ним превращаются в гибкие системы обмена сообщениями.Сервер:
socat UNIX-LISTEN:/tmp/app.sock,fork SYSTEM:'bash handler.sh'
Клиент:
echo "PING" | socat - UNIX-CONNECT:/tmp/app.sock
Отлично подходит для локальных API между скриптами.
Сервер:
socat TCP-LISTEN:9000,fork FILE:/var/log/app.log
Клиент:
socat - TCP:server:9000
Можно в реальном времени стримить логи или метрики.
socat EXEC:"cmd1" EXEC:"cmd2"
Аналог cmd1 | cmd2, но без ограничений пайпа (например, поддержка bidirectional).
socat - TCP:localhost:8080 | while read l; do
echo ">> $l"
done
Можно строить собственные протоколы поверх TCP.
Сервер:
socat TCP-LISTEN:7000,reuseaddr,fork SYSTEM:'bash rpc-handler.sh'
Клиент:
echo '{"cmd":"status"}' | socat - TCP:host:7000
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5👍2
Распределенный журнал событий через SSH fan-out
Иногда нужно собрать события с группы серверов и посмотреть их как единый хронологический поток: кто что делал, когда, и на каком хосте. Можно сделать это чисто на bash + SSH.
Для этого:
По SSH запускаем команду на каждом сервере (journalctl, tail, свой лог).
Добавляем timestamp + hostname.
Объединяем и сортируем и получаем общий timeline.
▪️ Fan-out по серверам
▪️ Централизованное объединение и сортировка
Теперь
BashTex📱 #bash
Иногда нужно собрать события с группы серверов и посмотреть их как единый хронологический поток: кто что делал, когда, и на каком хосте. Можно сделать это чисто на bash + SSH.
Для этого:
По SSH запускаем команду на каждом сервере (journalctl, tail, свой лог).
Добавляем timestamp + hostname.
Объединяем и сортируем и получаем общий timeline.
HOSTS=(srv1 srv2 srv3)
for h in "${HOSTS[@]}"; do
ssh "$h" "journalctl -n 50 --no-pager" | \
awk -v host="$h" '{print strftime("%s"), host, $0}' &
done
wait
{
for h in "${HOSTS[@]}"; do
ssh "$h" "journalctl -n 200 --no-pager" \
| awk -v host="$h" '{print strftime("%s"), host, $0}'
done
} | sort -n > timeline.log
Теперь
timeline.log выглядит так:
1712409123 srv1 sshd[1023]: Accepted password for admin
1712409124 srv3 systemd[1]: Started backup.
1712409125 srv2 docker[532]: Container restarted.
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Please open Telegram to view this post
VIEW IN TELEGRAM
😁20👍2
Ротация директорий
Когда нужно хранить несколько срезов состояния проекта или конфигов, удобно использовать ротацию директорий. Это быстрый, прозрачный и полностью файловый способ отката.
Предположим, у нас есть рабочая директория
Ротация выглядит так:
snapshot2 ← snapshot1 ← current
🛠 Скрипт ротации
➕ Преимущества
можно открыть любой снапшот обычным
откат в 1 команду:
работает для конфигов, кода и сервисов.
BashTex📱 #bash
Когда нужно хранить несколько срезов состояния проекта или конфигов, удобно использовать ротацию директорий. Это быстрый, прозрачный и полностью файловый способ отката.
Предположим, у нас есть рабочая директория
current/ и несколько ее копий:snapshot1/ - свежий слепокsnapshot2/ - предыдущийlast-good/ - стабильная проверенная версияРотация выглядит так:
snapshot2 ← snapshot1 ← current
BASE="/opt/myapp"
rotate() {
cd "$BASE" || exit 1
rm -rf snapshot2
mv snapshot1 snapshot2 2>/dev/null || true
cp -a current snapshot1
# Обновление last-good, если тесты прошли
if bash run_tests.sh; then
rm -rf last-good
cp -a current last-good
fi
}
rotate
cp -a быстрее архивации;можно открыть любой снапшот обычным
ls/cd;откат в 1 команду:
cp -a last-good currentработает для конфигов, кода и сервисов.
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Параллельный запуск задач с приоритетами
Когда нужно запускать много задач, но с разным приоритетом и контролем конкуренции, можно собрать простой планировщик задач. Мы создаем: очереди: high/, normal/, low/, локи для избежания гонок, запуск задач через nice - приоритеты ядра и минимальный воркер, который берет задачи по порядку.
▪️ Структура:
▪️ Воркер:
▪️ Добавление задачи:
▪️ Что это дает?
- Параллельные воркеры (запусти несколько экземпляров)
- Приоритеты через nice
- Исключение гонок через простые файловые lock-и
- Очередь можно смотреть, чистить, дебажить обычными инструментами
BashTex📱 #bash
Когда нужно запускать много задач, но с разным приоритетом и контролем конкуренции, можно собрать простой планировщик задач. Мы создаем: очереди: high/, normal/, low/, локи для избежания гонок, запуск задач через nice - приоритеты ядра и минимальный воркер, который берет задачи по порядку.
queue/
high/
normal/
low/
locks/
pick_task() {
for q in high normal low; do
t=$(ls queue/$q | head -n1 2>/dev/null)
[ -n "$t" ] && echo "$q/$t" && return
done
}
run() {
while true; do
task=$(pick_task)
[ -z "$task" ] && sleep 1 && continue
lock="locks/$(basename "$task").lock"
( set -o noclobber; >"$lock" ) 2>/dev/null || continue
cmd=$(cat "queue/$task")
rm "queue/$task"
case $task in
high/*) nice -n -10 bash -c "$cmd" ;;
normal/*) nice -n 0 bash -c "$cmd" ;;
low/*) nice -n 10 bash -c "$cmd" ;;
esac
rm -f "$lock"
done
}
run
echo "sleep 3 && echo DONE" > queue/high/job1
- Параллельные воркеры (запусти несколько экземпляров)
- Приоритеты через nice
- Исключение гонок через простые файловые lock-и
- Очередь можно смотреть, чистить, дебажить обычными инструментами
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Автопоиск подвисших сетевых соединений и перезапуск сервисов
Если сервис начинает подвисать, это часто видно по сети: соединения зависают в SYN-SENT, CLOSE-WAIT или сидят в одном состоянии слишком долго. Это можно определить прямо в bash, без netstat/ss.
1️⃣ Читаем таблицу соединений из /proc/net/tcp
Мы будем искать ошибочные или зависшие состояния.
2️⃣ Привязка inode к PID процесса. Каждый сокет отображается как
3️⃣ Перезапуск сервиса
▪️ Получаем:
- Автоматический поиск зависших TCP-соединений;
- Связь сокета с реальным процессом;
- Перезапуск только нужного сервиса;
Такой подход полезен для nginx, API-сервисов, баз данных и любых демонов, которые иногда залипают в сетевых состояниях.
BashTex📱 #bash #utils
Если сервис начинает подвисать, это часто видно по сети: соединения зависают в SYN-SENT, CLOSE-WAIT или сидят в одном состоянии слишком долго. Это можно определить прямо в bash, без netstat/ss.
Формат /proc/net/tcp содержит:
local addr/port
remote addr/port
state
inode (ключ!)
Мы будем искать ошибочные или зависшие состояния.
grep -E "$(echo $hung_states | sed 's/ /|/g')" /proc/net/tcp |
while read -r _ _ _ state _ _ _ _ inode _; do
echo "$inode"
done
/proc/$pid/fd/* → socket:[inode].
find_pid_by_inode() {
inode=$1
for p in /proc/[0-9]*/fd/*; do
if readlink "$p" 2>/dev/null | grep -q "socket:\[$inode\]"; then
echo "$p" | cut -d/ -f3
fi
done
}
for inode in $(get_hung_inodes); do
pid=$(find_pid_by_inode "$inode")
svc=$(ps -p "$pid" -o comm=)
echo "Hung socket in PID $pid ($svc)"
case "$svc" in
nginx) systemctl restart nginx ;;
sshd) systemctl restart sshd ;;
myapp) systemctl restart myapp ;;
esac
done
- Автоматический поиск зависших TCP-соединений;
- Связь сокета с реальным процессом;
- Перезапуск только нужного сервиса;
Такой подход полезен для nginx, API-сервисов, баз данных и любых демонов, которые иногда залипают в сетевых состояниях.
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
This media is not supported in your browser
VIEW IN TELEGRAM
Я думаю, что все устали и всем пора отдыхать, набираться сил. Все дедлайны позади, а о будущих думать пока не стоит!
Я пожелаю Вам хороших каникул, счастья, здоровья, поменьше выгорания и успехов в новом году!
С наступающим, 2026!
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥7🫡2
Многоуровневый логинг
Большинство скриптов просто пишут все в stdout или stderr. Но bash позволяет делать полноценный логгер, разделяя потоки по уровням и управлять ими динамически во время выполнения.
Для этого, выделяем отдельные файловые дескрипторы:
3> - INFO
4> - DEBUG
5> - ERROR
Каждый можно направить в свой файл или устройство.
▪️ Базовая инициализация логгеров
▪️ Лог-функции с проверкой уровня
▪️ Быстрое переключение уровня. Прямо в процессе выполнения можно менять уровень логов:
▪️ Перенаправление в консоль при необходимости. Например, показывать ERROR сразу на экране:
Или дебаг-режим в реальном времени:
BashTex📱 #bash #utils
Большинство скриптов просто пишут все в stdout или stderr. Но bash позволяет делать полноценный логгер, разделяя потоки по уровням и управлять ими динамически во время выполнения.
Для этого, выделяем отдельные файловые дескрипторы:
3> - INFO
4> - DEBUG
5> - ERROR
Каждый можно направить в свой файл или устройство.
LOGLEVEL="info" # debug|info|error
exec 3>info.log
exec 4>debug.log
exec 5>error.log
log_info() { [[ $LOGLEVEL =~ info|debug ]] && echo "[INFO] $*" >&3; }
log_debug() { [[ $LOGLEVEL == debug ]] && echo "[DEBUG] $*" >&4; }
log_error() { echo "[ERROR] $*" >&5; }
set_loglevel() {
LOGLEVEL="$1"
log_info "Loglevel switched to: $LOGLEVEL"
}
# Пример:
set_loglevel debug
exec 5> >(tee -a error.log >&2)
Или дебаг-режим в реальном времени:
exec 4> >(sed 's/^/[DBG]/' >&2)
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Bash-аналитика для iptables/nftables
Большинство сетевых политик обрастает десятками правил, но какие из них реально срабатывают, а какие просто мертвый груз? Разберемся и составим набор команд.
1️⃣ Статистика хитов iptables.
Поле
Мини-скрипт для выборки топ-работающих правил:
Покажет самые горячие правила.
2️⃣ nftables: счетчики + export
Bash-анализ:
3️⃣ Агрегация логов, какие действия реально происходят. Многие правила пишут в syslog (
Покажет, что именно чаще всего логирует firewall.
4️⃣ Комбинированный отчет
Такой небольшой пакет дает:
топ реальных срабатываний правил,
статистику нагрузочных цепочек,
понимание, что стоит оптимизировать или удалить.
BashTex📱 #bash #utils
Большинство сетевых политик обрастает десятками правил, но какие из них реально срабатывают, а какие просто мертвый груз? Разберемся и составим набор команд.
iptables хранит счетчики прямо в правилах:
iptables -L INPUT -v -n
Поле
pkts/bytes - это наши хиты.Мини-скрипт для выборки топ-работающих правил:
iptables -L INPUT -v -n \
| awk '/ACCEPT|DROP/ {printf "%10s %s\n", $1, $0}' \
| sort -nr
Покажет самые горячие правила.
nft list ruleset | grep -A1 'counter'
Bash-анализ:
nft list ruleset \
| awk '/counter/ {print $2, $3}' \
| sort -nr
LOG prefix "iptables-"). Вытащим статистику по префиксам:
grep "iptables-" /var/log/syslog \
| awk '{print $NF}' \
| sort | uniq -c | sort -nr
Покажет, что именно чаще всего логирует firewall.
echo "[HIT COUNTERS]"
iptables -L INPUT -v -n | awk '/ACCEPT|DROP/ {print $1, $0}' | sort -nr | head
echo "[LOG EVENTS]"
grep "iptables-" /var/log/syslog | awk '{print $NF}' \
| sort | uniq -c | sort -nr | head
Такой небольшой пакет дает:
топ реальных срабатываний правил,
статистику нагрузочных цепочек,
понимание, что стоит оптимизировать или удалить.
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
Оптимизация скорости загрузки сервера
Как находить медленные юниты, диагностировать зависшие цепочки и исправлять задержки
1️⃣ Кто тормозит: анализ времени запуска.
2️⃣ Поиск узкого места: критическая цепочка зависимостей. Если юнит стартует быстро, но висит в конце загрузки, то он блокирует чей-то старт или ждет зависимость. Нужно увидеть цепочку задержек:
3️⃣ Устраняем задержку через override. Правильный способ настроить юнит - это не менять оригинальный файл, а создать override:
В открывшийся файл:
Применяем изменения:
Корректируем цепочку зависимостей, чтобы Docker не ждал медленных сетевых юнитов.
BashTex📱 #bash #utils
Как находить медленные юниты, диагностировать зависшие цепочки и исправлять задержки
systemd-analyze blame показывает, какие юниты стартуют дольше всех, базовый шаг в поиске проблем.
systemd-analyze blame
systemd-analyze critical-chain
sudo systemctl edit docker.service
В открывшийся файл:
[Unit]
After=network.target
Wants=network.target
Применяем изменения:
sudo systemctl daemon-reload
sudo systemctl restart docker
Корректируем цепочку зависимостей, чтобы Docker не ждал медленных сетевых юнитов.
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Отслеживание активности пользователей
Linux хранит всю историю входов в три системные базы:
lastlog - последний логин каждого пользователя
utmp - текущие активные сессии
wtmp - история всех логинов/логаутов
Вот короткий набор инструментов, позволяющий получить максимум информации.
1️⃣ Последние входы всех пользователей (lastlog). Показать, кто реально входит в систему:
Фильтр подозрительно старых аккаунтов:
2️⃣ Активные сессии прямо сейчас
С IP, временем и TTY:
Выделение пользователей с нестандартных подсетей:
3️⃣ История всех входов/выходов
Кто заходил чаще всего:
Только удаленные логины:
4️⃣ Комбинированный отчет
BashTex📱 #bash #utils
Linux хранит всю историю входов в три системные базы:
lastlog - последний логин каждого пользователя
utmp - текущие активные сессии
wtmp - история всех логинов/логаутов
Вот короткий набор инструментов, позволяющий получить максимум информации.
lastlog | grep -v "Never logged in"
Фильтр подозрительно старых аккаунтов:
lastlog | awk '$4 ~ /Jan|Feb|Mar|Apr/ && $NF != "**Never**"'
who
С IP, временем и TTY:
who --ips
Выделение пользователей с нестандартных подсетей:
who --ips | awk '$5 !~ /^10\.|^192\.168\./'
last -F
Кто заходил чаще всего:
last | awk '{print $1}' | sort | uniq -c | sort -nr | head
Только удаленные логины:
last | grep -E "pts/[0-9]"
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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13
Обработка SSH-команд через connection pooling
Если вам нужно выполнить десятки или сотни SSH-команд подряд, стандартный подход ssh host cmd превращается в ад: каждый вызов открывает новое TCP-соединение, делает handshake, обмен ключами, проверку known_hosts и все это ради одной короткой команды. Но SSH умеет работать совершенно иначе, через
▪️ Включаем connection pooling. Создаем master-socket:
Теперь вторичные команды идут через master:
Все эти вызовы выполняются почти мгновенно.
▪️ Автоматизация: ~/.ssh/config. Чтобы не писать все вручную:
Теперь SSH сам создает и держит мастер-сессию 10 минут после последней команды.
▪️ Массовый запуск команд по списку
▪️ Завершение мастер-сессии
BashTex📱 #bash #utils
Если вам нужно выполнить десятки или сотни SSH-команд подряд, стандартный подход ssh host cmd превращается в ад: каждый вызов открывает новое TCP-соединение, делает handshake, обмен ключами, проверку known_hosts и все это ради одной короткой команды. Но SSH умеет работать совершенно иначе, через
multiplexing. Это когда одно физическое SSH-соединение становится трубой для десятков логических каналов. Команды выполняются без задержек, почти как локальные.
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"
Все эти вызовы выполняются почти мгновенно.
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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥2
Работа с архивами без распаковки
Распаковывать архив, чтобы посмотреть один файл - долго, неудобно и занимает место. К тому же большинство форматов позволяют работать прямо по месту.
1️⃣ Просмотр содержимого
2️⃣ Grep внутри архива (без извлечения)
tar позволяет выводить файлы в stdout, можно grep через pipe:
Или искать по всем файлам:
zip не умеет прямой потоковой выдачи всех файлов, но может вывести один:
7z (лучший вариант для grep по всем файлам)
Или по конкретному файлу:
3️⃣ Поиск файла по части имени
BashTex📱 #bash
Распаковывать архив, чтобы посмотреть один файл - долго, неудобно и занимает место. К тому же большинство форматов позволяют работать прямо по месту.
tar -tf archive.tar.gz # tar
unzip -l archive.zip # zip
7z l archive.7z # 7z
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"
7z l archive.7z | grep "\.conf"
tar -tf backup.tar | grep "nginx"
unzip -l logs.zip | grep ".log"
BashTex
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Автоматическая синхронизация каталогов по списку хостов
Когда один и тот же каталог нужно поддерживать в актуальном состоянии на нескольких серверах, самый простой инструмент:
▪️ Простой пример: синхронизация по списку хостов. Допустим, есть файл
🛠 Скрипт:
Скрипт:
Синхронизирует каталог на каждый хост;
Удаляет лишние файлы (
Передает только изменения (
Работает со сколько угодно хостами записанными в
▪️ Плюс: можно добавить контроль доступности
BashTex📱 #bash
Когда один и тот же каталог нужно поддерживать в актуальном состоянии на нескольких серверах, самый простой инструмент:
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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10
Проверка слабых паролей пользователей
Важно понимать: мы не проверяем сами пароли и не подбираем их. Мы только выявляем пользователей, у кого высокий риск слабого пароля, анализируя политики и метаданные.
▪️ Что можно проверить
Возраст пароля, если пароль не меняли 500+ дней - тревожный знак;
Минимальный и максимальный срок действия (политики
Пользователи с never expires, часто признак устаревших или слабозащищенных аккаунтов;
Аккаунты с неограниченным логином (
🛠 Скрипт
▪️ Чтение результатов
BashTex📱 #bash
Важно понимать: мы не проверяем сами пароли и не подбираем их. Мы только выявляем пользователей, у кого высокий риск слабого пароля, анализируя политики и метаданные.
Возраст пароля, если пароль не меняли 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8
Как находить зависшие задачи запущенные cron
Зависшие cron-задачи - это классика: скрипт повис в I/O, процесс ждет лок, завис ssh и сервер уже не делает регулярные бэкапы, не чистит кеши и не обновляет индексы. Но поймать такие случаи можно и нужно, я расскажу про самый простой способ: cron запускает процессы с PPID = PID cron’а или запускает их в окружении cron. Мы можем искать процессы, запущенные с COMMAND и PPID, и проверять их время жизни.
🛠 Скрипт
▪️ Настройка
Поставьте
Добавьте скрипт в
BashTex📱 #bash
Зависшие 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
Please open Telegram to view this post
VIEW IN TELEGRAM
👍10