fa
Feedback
BashTex | Linux

BashTex | Linux

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

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

نمایش بیشتر
2 526
مشترکین
-124 ساعت
اطلاعاتی وجود ندارد7 روز
+1730 روز
آرشیو پست ها
xargs против while read: где быстрее и безопаснее Обе конструкции позволяют обработать список файлов или строк, но работают они по-разному. Из-за этого одна может быть заметно быстрее, а другая - безопаснее. ▪️Когда выигрывает xargs Допустим, нужно удалить все .log-файлы:
find . -name "*.log" | xargs rm
xargs собирает несколько аргументов и передаёт их одной команде, поэтому вместо сотен запусков rm будет всего несколько. Для большого количества файлов разница в производительности может быть существенной. ▪️Но есть проблема По умолчанию xargs разделяет вход по пробелам и переводам строки. Если встретится файл:
my file.log
или
backup
2025.log
команда отработает некорректно. Безопасный вариант:
find . -name "*.log" -print0 | xargs -0 rm
Здесь разделителем становится символ NULL, поэтому пробелы и спецсимволы больше не проблема. ▪️Когда лучше while read Если над каждой строкой нужно выполнить несколько действий:
find . -name "*.log" -print0 |
while IFS= read -r -d '' file; do
    echo "Deleting: $file"
    rm "$file"
done
Такой код легче расширять: добавить проверки, логирование, условия или обработку ошибок. ▪️Что быстрее? Для простого запуска одной команды обычно выигрывает xargs. Для сложной логики, где каждая строка проходит несколько этапов обработки, удобнее использовать while read. ▪️Почему это важно Многие используют xargs и while read как взаимозаменяемые инструменты. На практике выбор зависит не только от скорости, но и от формата входных данных. Если есть вероятность встретить пробелы, переносы строк или необычные символы в именах файлов, безопасные варианты - xargs -0 или while read -d ''. BashTex 📱 #bash #linux

Анализ активных UNIX-сокетов: поиск неожиданных IPC-соединений При аудите обычно смотрят TCP- и UDP-порты, но многие сервисы вообще не используют сеть. Вместо этого они обмениваются данными через UNIX-сокеты. Именно поэтому их тоже стоит периодически проверять. ▪️Посмотреть все UNIX-сокеты Самый удобный способ:
ss -xl
Ключ -x показывает UNIX-сокеты, а -l - только те, которые находятся в режиме ожидания соединений. ▪️Получить больше информации Если нужны процессы-владельцы:
ss -xlp
Например:
u_str LISTEN 0 128 /run/docker.sock
users:(("dockerd",pid=812,fd=7))
Сразу видно, какой процесс создал сокет. ▪️На что обратить внимание Особый интерес представляют сокеты в нестандартных местах:
/tmp/
/dev/shm/
/home/user/
Большинство системных сервисов используют /run или /var/run. Если сокет появился в /tmp, стоит проверить, кто его создал и зачем. ▪️Найти сокеты через файловую систему
find / -type s 2>/dev/null
Это покажет все файлы типа socket, даже если они сейчас не используются. ▪️Когда это полезно UNIX-сокеты используют Docker, Podman, PostgreSQL, Redis, Nginx, PHP-FPM, systemd и десятки других сервисов. Неожиданный сокет может указывать на недавно установленное ПО, самописный сервис или процесс, который не должен работать на сервере. ▪️Почему это важно Во многих инцидентах внимание уделяют только открытым сетевым портам. Но локальный IPC тоже может стать точкой входа или способом взаимодействия между процессами. Проверка UNIX-сокетов помогает увидеть часть инфраструктуры, которая остаётся незаметной при обычном аудите сети. BashTex 📱 #bash #linux

📘 DevOps-инженер: от основ до продакшена — новый курс на Mentorix Пишете код, но деплой и прод — чёрный ящик? Курс про инжен
📘 DevOps-инженер: от основ до продакшена — новый курс на Mentorix Пишете код, но деплой и прод — чёрный ящик? Курс про инженерию эксплуатации: от первого сервера до автоматизированной CI/CD-инфраструктуры, которая держит нагрузку и не падает. ⚙️ Стек: Docker, Kubernetes, Ansible, Terraform, CI/CD, Prometheus + Grafana, логи ELK 🧩 Задания с автопроверкой + лабы в настоящем терминале 💻 Финальный проект в портфолио 🎓 Сертификат · доступ навсегда 🏷 −50% по промокоду DEVOPS50 — только 24 часа 9 990 ₽4 995 ₽Забрать курс со скидкой ━━━━━━━━━━━━━━ 🎁 А ещё на платформе — бесплатные курсы: Языки программированияGolang — основы языка 🦀 Rust — основы языка 🐍 Основы Python Инфраструктура и DevOps 🖥 Основы командной строки Linux 🐳 Docker: первые шаги 🔧 Git для начинающих Базы данныхSQL с нуляMongoDB с нуля 📚 Все бесплатные курсы Mentorix

Скрипт поиска процессов с аномальным потреблением памяти Когда на сервере заканчивается память, первое желание - открыть top. Но он показывает только текущее состояние. Для автоматизации удобнее получить список самых “тяжёлых” процессов и использовать его в скриптах. ▪️Быстрый рейтинг по RSS Размер физической памяти, занимаемой процессом (RSS), можно посмотреть так:
ps -eo pid,user,comm,rss --sort=-rss | head -10
Поле rss выводится в килобайтах, поэтому сразу видно, кто потребляет больше всего ОЗУ. ▪️Автоматическая проверка Например, вывести процессы, использующие больше 1 ГБ памяти:
ps -eo pid,comm,rss \
| awk '$3 > 1048576 {
    printf "%-8s %-20s %.1f MB\n", $1, $2, $3/1024
}'
Такой вывод уже удобно отправлять в отчёт или систему мониторинга. ▪️Если нужен максимум информации Часть данных о процессе хранится в /proc:
grep -E 'VmRSS|VmSize' /proc/1234/status
VmRSS - реально занятая физическая память. VmSize - всё адресное пространство процесса, включая ещё не загруженные страницы. Эти значения могут сильно отличаться. ▪️Не путайте RSS и VSZ Большой VSZ ещё не означает проблему. Многие приложения резервируют память заранее, но фактически используют лишь небольшую её часть. При поиске “пожирателей” памяти обычно ориентируются именно на RSS. ▪️Почему это важно Периодическая сортировка процессов по RSS помогает заметить утечки памяти ещё до того, как сработает OOM Killer. Особенно полезно для Java, Python, Node.js и других долгоживущих сервисов. BashTex 📱 #bash #linux

Проверка файловых систем, смонтированных с опасными опциями При аудите Linux обычно проверяют права доступа и SUID-биты. Но не менее важно посмотреть, как смонтированы файловые системы. Если временный каталог или пользовательский раздел смонтирован с exec, suid или dev, это может значительно расширить поверхность атаки. ▪️Посмотреть все точки монтирования Самый удобный способ:
findmnt -o TARGET,SOURCE,FSTYPE,OPTIONS
Или классический вариант:
mount
▪️На что обратить внимание Опции монтирования: • exec - разрешает запуск исполняемых файлов. • suid - позволяет работать SUID/SGID-битам. • dev - разрешает использование файлов устройств. Для каталогов вроде /tmp, /var/tmp или /dev/shm обычно безопаснее использовать противоположные опции: noexec,nosuid,nodev ▪️Пример проверки
findmnt -no TARGET,OPTIONS /tmp
Если вывод содержит:
rw,relatime
значит ограничения отсутствуют. Более безопасный вариант:
rw,nosuid,nodev,noexec
▪️Проверка через fstab Чтобы убедиться, что настройки сохранятся после перезагрузки:
grep -vE '^\s*#|^$' /etc/fstab
Ищите разделы, где для временных или пользовательских файловых систем не заданы защитные опции. ▪️Почему это важно Представьте, что злоумышленник смог записать файл в /tmp. Если раздел смонтирован с exec, его можно сразу запустить. Если ещё и разрешён suid или dev, последствия могут быть значительно серьёзнее. Несколько минут на проверку параметров монтирования могут устранить целый класс потенциальных проблем ещё до того, как они будут использованы. BashTex 📱 #scripts #linux

BashTex 📱 #мем
BashTex 📱 #мем

Автоматическая реакция на OOM через systemd и cgroups: перезапуск и контроль памяти OOM (Out Of Memory) - это не просто “закончилась память”. В Linux это механизм, при котором ядро начинает принудительно завершать процессы, чтобы система не упала целиком. Проблема в том, что без контроля первым под нож часто попадает не тот процесс, который должен. ▪️Как systemd влияет на OOM systemd работает поверх cgroups и может задавать приоритеты “жертвенности” процессов:
systemd-cgtop

Показывает, какие группы потребляют память.

▪️Контроль памяти на уровне unit

Можно ограничить сервис:

[Service]
MemoryMax=500M

Теперь процесс физически не сможет превысить лимит.

Дополнительно:

MemoryHigh=400M
Это мягкий порог - systemd начинает давить на процесс раньше, чем наступит OOM. ▪️Влияние на OOM Killer Можно управлять приоритетом уничтожения:
OOMScoreAdjust=-500
или наоборот:
OOMScoreAdjust=500
Чем выше значение - тем выше шанс, что процесс будет убит первым. ▪️Автоматический перезапуск после OOM systemd может перезапускать сервис даже после убийства ядром:
[Service]
Restart=on-failure
RestartSec=2
Это работает и для OOM-kill, потому что процесс считается завершённым с ошибкой. ▪️Практический сценарий Типичная ситуация: • сервис разогнал память • ядро убивает его через OOM • systemd фиксирует падение • запускает новый экземпляр • cgroups не дают повторно выйти за лимит ▪️Где начинается реальный контроль Ключевой момент - сочетание: • MemoryMax (жёсткий лимит) • MemoryHigh (раннее давление) • OOMScoreAdjust (приоритет убийства) • Restart=on-failure (самовосстановление) ▪️Почему это важно Без cgroups OOM - это хаос: ядро выбирает жертву само. С systemd это превращается в управляемую систему: процесс либо не доходит до OOM, либо корректно переживает его через перезапуск и ограничение ресурсов. BashTex 📱 #scripts #linux

nameref (declare -n): ссылки на переменные и передача массивов в функции В Bash функции по умолчанию работают с копиями значений или с глобальными переменными. Но есть механизм, который позволяет имитировать “ссылки” - nameref. ▪️Что такое nameref declare -n создаёт ссылку на другую переменную:
arr=(1 2 3)

declare -n ref=arr
ref[0]=999

echo "${arr[0]}"
Результат:
999
ref не хранит данные - он указывает на arr. ▪️Передача массива в функцию без копирования Классическая проблема:
func() {
  local arr=("$@")
}
Это создаёт копию массива. С nameref:
func() {
  local -n arr=$1
  echo "${arr[0]}"
}
Вызов:
data=(10 20 30)
func data
Функция работает с оригинальным массивом. ▪️Модификация массива внутри функции
func() {
  local -n arr=$1
  arr[1]=999
}

data=(10 20 30)
func data

echo "${data[@]}"
Результат:
10 999 30
▪️Где это особенно полезно функции обработки конфигураций парсинг JSON → массивы ключей/значений работа с таблицами данных построение библиотек на Bash без глобальных переменных ▪️Важный момент nameref работает только с именами переменных:
local -n ref=$1
Нельзя передавать: • значения • выражения • результаты команд Только имя переменной. ▪️Ограничения нельзя безопасно переиспользовать ссылку на разные переменные в одном scope без переопределения сложнее отлаживать (меняется оригинальный объект) требует Bash 4.3+ ▪️Почему это важно Без nameref Bash-функции либо копируют данные, либо используют глобальное состояние. declare -n даёт третий вариант — передачу по ссылке, что делает сложные скрипты заметно чище и ближе к языкам общего назначения. BashTex 📱 #scripts #linux

coproc на практике: двусторонний обмен данными с процессом В bash обычно все сводится к pipe: команда - команда. Но классический пайп односторонний. Если нужен диалог с процессом в обе стороны - используется coproc. ▪️ Что такое coproc. Он запускает процесс и даёт два канала: stdin - в процесс stdout - из процесса И все это без временных файлов и костылей с FIFO. ▪️ Базовый пример

coproc BC { bc -l; }
Теперь у нас есть процесс калькулятора, с которым можно общаться. Отправляем данные:

echo "2+2" >&"${BC[1]}"
read result <&"${BC[0]}"
echo "$result"
▪️ Как это устроено. После запуска bash создает массив:

${COPROC[0]} # stdout процесса
${COPROC[1]} # stdin процесса
Можно читать и писать независимо. ▪️ Реальный кейс: фоновый parser

coproc JSON { jq -c '.name'; }
Отправляем поток данных:

echo '{"name":"test"}' >&"${JSON[1]}"
read out <&"${JSON[0]}"
echo "$out"
▪️ Почему это лучше pipe Pipe работает так:

cmd1 | cmd2
Но: • нет обратного канала • процесс заканчивается сразу • нельзя поддерживать состояние coproc позволяет держать живой процесс и общаться с ним как с сервисом. ▪️ Важный момент. Процесс внутри coproc не перезапускается автоматически. Если он завершился - каналы перестают работать, и это нужно проверять вручную. ▪️ Где это реально полезно • интерактивные CLI-инструменты (bc, python, sqlite3) • долгоживущие парсеры (jq, awk, кастомные демоны) • проксирование данных между процессами • построение "мини-сервисов" прямо в Bash coproc превращает bash из набора команд в примитивную систему IPC, где процессы начинают вести диалог, а не просто передавать поток данных в одну сторону. BashTex 📱 #bash #scripts

Подготовка к DevOps/SRE интервью с «Troubleshooting Docker и Kubernetes: поиск и устранение проблем» В программе только важны
Подготовка к DevOps/SRE интервью с «Troubleshooting Docker и Kubernetes: поиск и устранение проблем» В программе только важные аспекты: — troubleshooting Docker и образов — диагностика сетевых проблем — настройка readiness/liveness probes — отладка pod’ов, деплоев и ingress — анализ логов контейнеров и кластера — разбор ошибок CrashLoopBackOff, OOMKilled, ImagePullBackOff и других Собеседования на DevOps/SRE сейчас всё чаще строятся вокруг реальных инцидентов. Данный курс фокусируется именно на таких сценариях и помогает в подготовке к практическим вопросам 48 часов доступен со скидкой 25% ↗️ Пройти курс на Stepik

Bash strict mode: что реально даёт set -euo pipefail и где он ломает логику В Bash часто добавляют так называемый “strict mode”:
set -euo pipefail
Идея простая - сделать скрипты более предсказуемыми и ловить ошибки раньше. ▪️Что означает каждая опция -e → остановить скрипт при любой ошибке команды -u → ошибка при использовании неинициализированной переменной -o pipefail → пайп считается упавшим, если упала любая команда в цепочке ▪️Что это реально улучшает Без strict mode многие ошибки “проглатываются”:
rm file_not_exist
echo "continue"

С 
-e
 скрипт остановится сразу.

Или:

echo "$UNDEFINED_VAR"

С 
-u
 будет явная ошибка, а не пустая строка.

▪️
pipefail: скрытая проблема пайпов

Без него:

cat file | grep ERROR | sort

Возвращает код последней команды, даже если 
grep
 упал.

С 
pipefail
 - ошибка ловится корректно.

▪️
Где начинается проблема
Strict mode ломает сценарии, где “ошибка - это нормальное состояние”.

Пример:

grep pattern file.txt
echo "done"

Если совпадений нет, 
grep
 возвращает 1 → скрипт завершается, хотя это не ошибка логики.

▪️
Типичный workaround
grep pattern file.txt || true

Или:

set +e
grep pattern file.txt
set -e
Но это уже ручное управление поведением. ▪️ещё один частый кейс - test / if
set -e

if grep pattern file.txt; then
  echo "found"
fi
Здесь grep может “упасть”, но в контексте if это нормальный контроль потока - и это не считается фатальной ошибкой. ▪️Итоговый баланс Strict mode хорошо работает в: • CI/CD • одноразовых скриптах • автоматизации без ветвлений Но начинает мешать в: • парсинге данных • поиске (grep как логика) • скриптах с ожидаемыми “ошибками как состоянием” Это не универсальная защита, а переключатель модели поведения Bash-скрипта: от “гибкого” к “строго детерминированному”. BashTex 📱 #scripts #linux

BashTex 📱 #мем
BashTex 📱 #мем

Работа с дескрипторами файлов через exec: FD 3, 4, логирование и контроль потоков В Bash обычно работают только с stdin (0), stdout (1) и stderr (2). Но файловые дескрипторы на этом не заканчиваются - можно использовать FD 3, 4 и выше для более гибкого управления потоками. ▪️Базовая идея Каждый процесс имеет таблицу файловых дескрипторов:
0 → stdin
1 → stdout
2 → stderr
Но можно открыть дополнительные:
exec 3>debug.log
Теперь FD 3 пишет в файл debug.log. ▪️Разделение логов Классический приём - разделить обычный вывод и отладку:
echo "normal output"
echo "debug info" >&3
Результат: stdout остаётся чистым debug уходит в отдельный файл ▪️Перенаправление команд через FD Можно связать вывод команды с кастомным дескриптором:
exec 4< input.txt
Теперь FD 4 читает файл как поток. Чтение:
read -u 4 line
echo "$line"
▪️Логирование через единый канал Удобный паттерн - централизованный лог: exec 3>>/var/log/myapp.log
log() {
  echo "$(date '+%F %T') $*" >&3
}
Теперь все логи идут через FD 3, без захламления stdout. ▪️Почему это лучше обычного >> везде единая точка управления логированием проще отключать/перенаправлять вывод можно динамически менять файл логов через exec ▪️Закрытие дескрипторов
exec 3>&-
FD освобождается, файл больше не удерживается процессом. ▪️Где это реально используется сложные Bash-скрипты с несколькими потоками данных системы логирования без внешних библиотек обработка нескольких входных источников одновременно изоляция debug/production вывода FD выше 2 - это недооценённый инструмент, который превращает Bash из набора команд в полноценную систему управления потоками. BashTex 📱 #scripts #linux

Проверка недавно созданных пользователей: UID, shell и следы активности На сервере часто важно быстро понять, появлялись ли новые пользователи и насколько они “нормальные”. Один из базовых источников - /etc/passwd, но там нет явной даты создания. Поэтому анализ строится через косвенные признаки. ▪️Поиск пользователей с обычным UID диапазоном getent passwd | awk -F: '$3 >= 1000 {print $1, $3, $7}' Обычно реальные пользователи находятся начиная с UID 1000. Системные - ниже. Смотрим shell: /bin/bash, /bin/zsh чаще у людей, /usr/sbin/nologin или /bin/false - сервисные аккаунты. ▪️Быстрый срез через lastlog
lastlog -t 30
Показывает пользователей, которые логинились за последние 30 дней. Новые аккаунты без активности сразу заметны. ▪️Проверка событий создания пользователей
journalctl _COMM=useradd --since "7 days ago"
или через auth лог:
grep useradd /var/log/auth.log
Здесь видны факты создания аккаунтов и изменения групп. ▪️Косвенная проверка “новизны” Можно оценить свежесть через системные изменения:
stat /etc/passwd
или изменения shadow:
stat /etc/shadow
Если недавно был добавлен пользователь, эти файлы будут обновлены в тот же период. ▪️Дополнительная проверка активности
faillog -a
и
last
Позволяют понять, пытался ли пользователь входить в систему и с каких хостов. ▪️Почему это важно Новые пользователи с UID 1000+, нестандартным shell или отсутствием логинов — один из первых сигналов, который стоит проверять при аудите сервера. BashTex 📱 #scripts #du

Почему kill -9 - не лучший способ остановить процесс Многие администраторы при зависшем процессе сразу используют:
kill -9 <PID>
Обычно это работает. Но далеко не всегда это правильное решение. ▪️Что делает SIGKILL Сигнал -9 (SIGKILL) принудительно завершает процесс на уровне ядра. Процесс не может его перехватить, обработать или проигнорировать. Ядро просто убивает его. ▪️Что при этом не происходит Процесс не успевает: сохранить данные закрыть файлы завершить активные операции удалить временные файлы выполнить обработчики завершения Например, база данных может не успеть корректно завершить транзакции. ▪️Что использовать сначала Обычный сигнал завершения:
kill <PID>
или
kill -15 <PID>
Это SIGTERM. Процесс получает запрос на завершение и может корректно освободить ресурсы. ▪️Посмотреть, реагирует ли процесс Отправляем SIGTERM:
kill -15 1234
Проверяем:
ps -p 1234
Если процесс всё ещё работает спустя разумное время, тогда можно переходить к более жёстким мерам. ▪️Полезный приём Для сервисов под systemd лучше использовать:
systemctl stop myapp
systemd сам отправит нужные сигналы в правильном порядке и подождёт завершения процесса. Только если сервис не реагирует, будет применено принудительное завершение. ▪️Почему это важно kill -9 часто помогает быстро решить проблему, но одновременно может создавать новые. Поэтому его лучше рассматривать как последний инструмент, когда процесс уже не отвечает на обычное завершение. BashTex 📱 #scripts #kill9

Почему du и df показывают разный размер Одна из классических загадок Linux:
df -h
Показывает:
/dev/sda1  100%
Но если проверить содержимое файловой системы:
du -sh /var
du -sh /home
du -sh /opt
Суммарный объём получается заметно меньше. Куда пропало место? ▪️Что считают du и df du подсчитывает размер файлов, которые видны в файловой системе. df показывает занятые блоки на уровне самой файловой системы. Из-за этого их значения могут различаться. ▪️Самая частая причина Удалённый файл всё ещё открыт процессом. Например:
rm app.log
Файл исчез из каталога, поэтому du его больше не видит. Но если процесс продолжает писать в него, место останется занятым. Найти такие файлы можно так:
lsof +L1
Пример вывода:
java 1234 user 5w REG ... app.log (deleted)
Пока процесс не завершится или не закроет дескриптор, место не освободится. ▪️Другие причины Зарезервированные блоки ext4:
tune2fs -l /dev/sda1 | grep Reserved
Смонтированные файловые системы внутри каталогов:
mount | column -t
Или bind-монтирования, из-за которых данные учитываются неожиданным образом. ▪️Быстрая диагностика Если диск внезапно заполнился:
df -h
lsof +L1
Во многих случаях проблема обнаруживается уже на втором шаге. ▪️Почему это важно На продакшн-серверах часто удаляют огромный лог в надежде освободить место. Но если процесс продолжает держать файл открытым, свободное пространство не появится, а приложение может вскоре упасть из-за нехватки диска. BashTex 📱 #scripts #du

tmpfiles.d: автоматическое создание и очистка директорий без cron На многих серверах можно встретить скрипты, которые создают нужные каталоги при загрузке системы или периодически чистят временные файлы через cron. Хотя systemd умеет делать это самостоятельно. ▪️Что такое tmpfiles.d Механизм tmpfiles.d позволяет создавать каталоги, менять права доступа, владельцев и автоматически удалять старые файлы по заданным правилам. Конфигурации обычно находятся здесь:
/etc/tmpfiles.d/
/usr/lib/tmpfiles.d/
▪️Создание каталога при старте Допустим, приложению нужен каталог для кэша:
d /var/cache/myapp 0755 myapp myapp -
Где: d — создать директорию 0755 — права доступа myapp myapp — владелец и группа После применения:
systemd-tmpfiles --create
Каталог появится автоматически. ▪️Автоматическая очистка Удалять файлы старше 7 дней:
D /var/tmp/myapp 0755 myapp myapp 7d
Теперь systemd будет очищать содержимое каталога согласно политике хранения. Проверить правила можно так:
systemd-tmpfiles --clean
▪️Где это полезно Кэш приложений, временные выгрузки, очереди обработки файлов, каталоги с отчётами и любые данные, которые должны жить ограниченное время. ▪️Почему это удобнее cron Вместо отдельных скриптов и задач в планировщике вся логика хранения описывается одной строкой конфигурации. Создание, права доступа и очистка управляются стандартными средствами системы. BashTex 📱 #scripts #tmpfiles

Почему журналы journald могут неожиданно заполнить диск На сервере закончилось место, а в /var/log ничего подозрительного нет? Часто виновником оказывается journald. ▪️Где хранятся логи Проверить объём журналов можно одной командой:
journalctl --disk-usage
Например:
Archived and active journals take up 2.8G on disk.
На серверах с большим количеством сервисов объём может расти довольно быстро. ▪️Посмотреть самые “тяжёлые” журналы Узнать, сколько данных записывается за последние сутки:
journalctl --since yesterday | wc -l
А если какой-то сервис генерирует тысячи сообщений в минуту:
journalctl -u myapp.service
Обычно проблема находится довольно быстро. ▪️Как очистить старые журналы Оставить только последние 500 МБ:
journalctl --vacuum-size=500M
Или удалить записи старше 14 дней:
journalctl --vacuum-time=14d
Очистка происходит без остановки journald. ▪️Ограничение роста журналов Настройки находятся в:
/etc/systemd/journald.conf
Например:
SystemMaxUse=1G
SystemKeepFree=2G
После изменения конфигурации:
systemctl restart systemd-journald
▪️Почему это важно Когда приложение начинает писать ошибки в цикле, journald может вырасти до нескольких гигабайт за считанные часы. Если заранее не настроить лимиты, одна неудачная конфигурация способна оставить сервер без свободного места. BashTex 📱 #scripts #systemd

PIPESTATUS: как узнать, где именно сломался пайп Большинство администраторов знают про $?, но при работе с пайпами он может вводить в заблуждение. Посмотрим на пример:
grep ERROR app.log | sort | uniq
echo $?
Если пайп состоит из нескольких команд, $? покажет код возврата только последней из них. Если grep завершился с ошибкой, а uniq отработал успешно, вы увидите:
0
Хотя одна из команд фактически провалилась. ▪️Решение - PIPESTATUS После выполнения пайпа Bash сохраняет коды возврата всех его команд в массиве PIPESTATUS:
grep ERROR app.log | sort | uniq

echo "${PIPESTATUS[@]}"
Результат может выглядеть так:
2 0 0
Здесь видно, что ошибка произошла именно в grep. ▪️Проверка конкретного этапа Можно обратиться к нужному элементу массива:
grep ERROR app.log | sort | uniq

echo "${PIPESTATUS[0]}"
Проверяем первую команду в цепочке.
echo "${PIPESTATUS[1]}"
Проверяем вторую. ▪️А что насчёт pipefail? Многие включают:
set -o pipefail
Это полезно — теперь пайп вернёт ошибку, если упала любая команда внутри него. Но pipefail не показывает, какой именно этап завершился неудачно. Для диагностики всё равно пригодится PIPESTATUS. ▪️Почему это важно Если в скрипте есть длинные цепочки из grep, awk, sed, jq, sort и других утилит, обычный $? может скрыть проблему. PIPESTATUS позволяет быстро понять, где именно произошёл сбой. BashTex 📱 #scripts #pipestatus

flock: защита от повторного запуска скрипта Одна из самых неприятных проблем в автоматизации - случайный запуск нескольких копий одного скрипта. Например, cron запускает задачу каждые 5 минут, но одна из прошлых итераций ещё не завершилась. В результате появляются дублирующиеся процессы, конфликты при работе с файлами и непредсказуемые ошибки. ▪️Типичная ошибка Допустим, скрипт выполняется 10 минут, а cron запускает его каждые 5:
*/5 * * * * /opt/backup.sh
Через некоторое время одновременно будут работать сразу несколько экземпляров. ▪️Решение через flock Самый простой вариант - добавить блокировку:
flock -n /tmp/backup.lock /opt/backup.sh
Если lock-файл уже занят другим процессом, новая копия просто не запустится. Ключ -n означает “не ждать освобождения блокировки”. ▪️Использование внутри скрипта Можно защитить сам скрипт независимо от способа запуска:
exec 200>/var/run/myjob.lock

flock -n 200 || {
  echo "Already running"
  exit 1
}
Теперь второй экземпляр завершится сразу после старта. ▪️Чем лучше PID-файлов Многие делают так:
echo $$ > /tmp/script.pid
Но после аварийного завершения PID-файл может остаться, а PID уже будет принадлежать другому процессу. flock работает через файловые дескрипторы ядра и автоматически освобождает блокировку при завершении процесса. ▪️Где особенно полезно Бэкапы, синхронизация файлов, обработка очередей, обновление данных, cron-задачи и любые скрипты, которые нельзя запускать параллельно. BashTex 📱 #scripts #flock