fa
Feedback
BashTex | Linux

BashTex | Linux

رفتن به کانال در Telegram

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

نمایش بیشتر
2 524
مشترکین
اطلاعاتی وجود ندارد24 ساعت
-67 روز
+230 روز
آرشیو پست ها
Массовое переименование файлов по шаблону ▪️ Вариант 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

Как находить зависшие задачи запущенные 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

Проверка слабых паролей пользователей Важно понимать: мы не проверяем сами пароли и не подбираем их. Мы только выявляем пользователей, у кого высокий риск слабого пароля, анализируя политики и метаданные. ▪️ Что можно проверить Возраст пароля, если пароль не меняли 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

Когда на новый год попросил побольше ОП, но почему-то теперь вместо винды стоит линукс 😁 BashTex 📱 #юмор
Когда на новый год попросил побольше ОП, но почему-то теперь вместо винды стоит линукс 😁 BashTex 📱 #юмор

Автоматическая синхронизация каталогов по списку хостов Когда один и тот же каталог нужно поддерживать в актуальном состоянии на нескольких серверах, самый простой инструмент: 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

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

Обработка 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

Отслеживание активности пользователей 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

Оптимизация скорости загрузки сервера Как находить медленные юниты, диагностировать зависшие цепочки и исправлять задержки 1️⃣ Кто тормозит: анализ времени запуска. systemd-analyze blame показывает, какие юниты стартуют дольше всех, базовый шаг в поиске проблем.

systemd-analyze blame
2️⃣ Поиск узкого места: критическая цепочка зависимостей. Если юнит стартует быстро, но висит в конце загрузки, то он блокирует чей-то старт или ждет зависимость. Нужно увидеть цепочку задержек:

systemd-analyze critical-chain
3️⃣ Устраняем задержку через override. Правильный способ настроить юнит - это не менять оригинальный файл, а создать override:

sudo systemctl edit docker.service
В открывшийся файл:

[Unit]
After=network.target
Wants=network.target
Применяем изменения:

sudo systemctl daemon-reload
sudo systemctl restart docker
Корректируем цепочку зависимостей, чтобы Docker не ждал медленных сетевых юнитов. BashTex 📱 #bash #utils

Подборка каналов IT от наших друзей: 🦥 Lazy_Programmer – Для ленивых 📲 Lazy_Programmer – В MAXе тоже есть место для лени 🤩 iwannabeprogrammer  — IT-мемы 📲 iwannabeprogrammer – Мы в MAX 🎬 videos_it  — База видеоуроков по IT 🐧 Linux_Club — Для Linuxоидов 📔 BOOKS — Читать не перечитать 🇷🇺 our_computer — У нас как в СССР 🔐 LazySecurity — Канал по ИБ 🔥 floppydisky — ITUMOR 📱 codebase_frontend — Красим кнопки ➡️ LazyDevOps —  Канал для дев и псов 🐈‍⬛️ LazyTester — Протестируй канал!

Bash-аналитика для iptables/nftables Большинство сетевых политик обрастает десятками правил, но какие из них реально срабатывают, а какие просто мертвый груз? Разберемся и составим набор команд. 1️⃣ Статистика хитов iptables. iptables хранит счетчики прямо в правилах:

iptables -L INPUT -v -n
Поле pkts/bytes - это наши хиты. Мини-скрипт для выборки топ-работающих правил:

iptables -L INPUT -v -n \
  | awk '/ACCEPT|DROP/ {printf "%10s %s\n", $1, $0}' \
  | sort -nr
Покажет самые горячие правила. 2️⃣ nftables: счетчики + export

nft list ruleset | grep -A1 'counter'
Bash-анализ:

nft list ruleset \
  | awk '/counter/ {print $2, $3}' \
  | sort -nr
3️⃣ Агрегация логов, какие действия реально происходят. Многие правила пишут в syslog (LOG prefix "iptables-"). Вытащим статистику по префиксам:

grep "iptables-" /var/log/syslog \
  | awk '{print $NF}' \
  | sort | uniq -c | sort -nr
Покажет, что именно чаще всего логирует firewall. 4️⃣ Комбинированный отчет

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 📱 #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
▪️ Перенаправление в консоль при необходимости. Например, показывать ERROR сразу на экране:

exec 5> >(tee -a error.log >&2)
Или дебаг-режим в реальном времени:

exec 4> >(sed 's/^/[DBG]/' >&2)
BashTex 📱 #bash #utils

Дедлайн Новый год стучится в дверь! 😊 Я думаю, что все устали и всем пора отдыхать, набираться сил. Все дедлайны позади, а о будущих думать пока не стоит! 😊 Я пожелаю Вам хороших каникул, счастья, здоровья, поменьше выгорания и успехов в новом году! 😊 С наступающим, 2026! 😊

Автопоиск подвисших сетевых соединений и перезапуск сервисов Если сервис начинает подвисать, это часто видно по сети: соединения зависают в SYN-SENT, CLOSE-WAIT или сидят в одном состоянии слишком долго. Это можно определить прямо в bash, без netstat/ss. 1️⃣ Читаем таблицу соединений из /proc/net/tcp
Формат /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
2️⃣ Привязка inode к PID процесса. Каждый сокет отображается как /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
}
3️⃣ Перезапуск сервиса

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 📱 #bash #utils

На Stepik вышел курс по Linux Внутри 20+ модулей: от установки Linux и работы с файлами до сетей, прав, дисков, процессов, автоматизации на Bash и многого другого. Всё сразу закрепляется на практике (200+ заданий с автопроверкой) Материал подаётся понятным языком, шаг за шагом, на реальных примерах и с наглядными схемами. После прохождения вы получите сертификат, который можно добавить в резюме. Есть бесплатные демо-уроки для ознакомления. В ближайшие 48ч курс доступен со скидкой 25% по промокоду «ADMIN25»: открыть курс на Stepik P.S. Курс можно купить в подарок на Новый год

Параллельный запуск задач с приоритетами Когда нужно запускать много задач, но с разным приоритетом и контролем конкуренции, можно собрать простой планировщик задач. Мы создаем: очереди: 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 📱 #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 📱 #bash

Ну уж нет BashTex 📱 #юмор
Ну уж нет BashTex 📱 #юмор

Распределенный журнал событий через SSH fan-out Иногда нужно собрать события с группы серверов и посмотреть их как единый хронологический поток: кто что делал, когда, и на каком хосте. Можно сделать это чисто на bash + SSH. Для этого: По SSH запускаем команду на каждом сервере (journalctl, tail, свой лог). Добавляем timestamp + hostname. Объединяем и сортируем и получаем общий timeline. ▪️ Fan-out по серверам

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 📱 #bash

Использование socat как универсального канала между скриптами socat позволяет связать любой источник данных с любым приемником. Bash-скрипты с ним превращаются в гибкие системы обмена сообщениями. ▪️ Bash через UNIX-сокет. Мини-IPC без tmp-файлов и named pipes: Сервер:

socat UNIX-LISTEN:/tmp/app.sock,fork SYSTEM:'bash handler.sh'
Клиент:

echo "PING" | socat - UNIX-CONNECT:/tmp/app.sock
Отлично подходит для локальных API между скриптами. 2️⃣ Передача данных между серверами (TCP) Сервер:

socat TCP-LISTEN:9000,fork FILE:/var/log/app.log
Клиент:

socat - TCP:server:9000
Можно в реальном времени стримить логи или метрики. 3️⃣ Замена сложных пайпов. Напрямую соединяем процессы, даже если они не умеют работать с stdin/stdout:

socat EXEC:"cmd1" EXEC:"cmd2"
Аналог cmd1 | cmd2, но без ограничений пайпа (например, поддержка bidirectional). 4️⃣ Двунаправленный канал в скрипте. Например, общение с интерактивным сервисом:

socat - TCP:localhost:8080 | while read l; do
    echo ">> $l"
done
Можно строить собственные протоколы поверх TCP. 5️⃣ Быстрый импровизированный RPC Сервер:

socat TCP-LISTEN:7000,reuseaddr,fork SYSTEM:'bash rpc-handler.sh'
Клиент:

echo '{"cmd":"status"}' | socat - TCP:host:7000
BashTex 📱 #bash #utils