BashTex | Linux
Открыть в Telegram
Авторский канал для тех, кто хочет глубже погрузиться в мир Linux. Подойдет для разработчиков, системных администраторов и DevOps Реклама: @dad_admin
Больше2 521
Подписчики
-224 часа
-87 дней
+1630 дней
Архив постов
2 521
Анализ активных UNIX-сокетов:
ss -xl и неожиданные IPC-соединения
Когда ищут открытые сервисы на сервере, обычно проверяют TCP и UDP:
ss -tulpn
Но часть процессов вообще не использует сеть. Они общаются через UNIX-сокеты - локальный механизм IPC между процессами.
▪️Посмотреть активные UNIX-сокеты
ss -x
Ключ -x включает UNIX-сокеты.
Чтобы увидеть только ожидающие подключения:
ss -xl
Пример:
u_str LISTEN 0 128 /run/docker.sock
Это означает, что какой-то процесс принимает локальные подключения через этот сокет.
▪️Найти владельца сокета
Добавляем информацию о процессе:
ss -xlp
Пример:
users:(("dockerd",pid=842,fd=7))
Теперь понятно, какой процесс создал точку обмена.
▪️Проверка прав доступа
UNIX-сокет - это файл, поэтому у него есть обычные права:
ls -l /run/docker.sock
Например:
srw-rw---- root docker docker.sock
Группа с правом записи может управлять Docker через этот сокет.
▪️Найти все сокеты на диске
find / -type s 2>/dev/null
Особое внимание:
/tmp
/dev/shm
/home/*
Системные сервисы чаще используют:
/run /var/run
▪️Посмотреть, кто держит конкретный сокет
Через lsof:
lsof /run/docker.sock
или:
fuser /run/docker.sock
▪️Почему это важно
Открытый TCP-порт виден сразу при сетевом сканировании. UNIX-сокеты остаются внутри системы и часто забываются при аудите.
При проверке сервера стоит смотреть не только наружные соединения, но и локальные каналы связи между процессами: именно там могут находиться Docker API, базы данных, агенты мониторинга и другие сервисы с важными правами доступа.
BashTex 📱 #bash #linux2 521
tee не только для логов: запись сразу в несколько потоков
Большинство используют tee только для сохранения вывода команды в файл:
command | tee output.log
Но возможности tee этим не ограничиваются. Он позволяет разветвлять поток данных и отправлять его сразу в несколько мест.
▪️Запись в несколько файлов
Например, сохранить один и тот же вывод сразу в два файла:
dmesg | tee kernel.log backup.log >/dev/null
Не нужно запускать команду дважды - tee сам продублирует поток.
▪️Логирование без потери вывода
Если скрипт должен писать лог, но при этом вывод оставаться в терминале:
./backup.sh | tee backup.log
Пользователь видит процесс выполнения, а лог сохраняется автоматически.
▪️Добавление вместо перезаписи
По умолчанию tee перезаписывает файл.
Чтобы дописывать:
echo "Started" | tee -a app.log
Ключ -a работает так же, как >>.
▪️Передача сразу в несколько команд
Вместе с process substitution можно построить разветвление потока:
journalctl -f \
| tee >(grep ERROR > errors.log) \
>(wc -l > count.txt) \
> /dev/null
Теперь один поток одновременно:
фильтруется по ошибкам;
подсчитывается;
может использоваться в других обработчиках.
Команда journalctl при этом запускается только один раз.
▪️Почему это важно
tee - это не просто инструмент для записи логов. Он позволяет строить конвейеры, где один источник данных обслуживает сразу несколько получателей. Это особенно полезно при анализе логов, мониторинге и автоматизации, когда дорого или невозможно повторно запускать исходную команду.
BashTex 📱 #bash #linux2 521
wait и wait -n: управление несколькими фоновыми задачами
Запустить процесс в фоне через & умеют почти все. Проблемы начинаются, когда таких процессов становится несколько и нужно понять, кто завершился и с каким кодом ошибки.
▪️Базовый wait
sleep 2 &
sleep 5 &
wait
echo "Все процессы завершились"
Без аргументов wait ждёт завершения всех фоновых задач текущего shell.
▪️Ожидание конкретного процесса
sleep 10 &
pid=$!
wait "$pid"
echo "Процесс завершён"
$! - PID последнего фонового процесса.
▪️Зачем нужен wait -n
Появился в Bash 4.3+ и решает важную задачу: ждать не всех, а первого завершившегося процесса.
sleep 5 &
sleep 2 &
sleep 8 &
wait -n
echo "Кто-то уже завершился"
Скрипт продолжит работу через 2 секунды, а не через 8.
▪️Практический сценарий
Параллельная обработка файлов:
for file in *.log; do
gzip "$file" &
done
while wait -n; do
echo "Одна задача завершилась"
done
Так можно реагировать на завершение задач по мере их выполнения, а не ждать самый медленный процесс.
▪️Почему это важно
Без wait Bash может завершить скрипт раньше фоновых процессов. А wait -n позволяет строить простые очереди задач и параллельную обработку без GNU Parallel, Python и других внешних инструментов. Для многих серверных скриптов этого уже достаточно.
BashTex 📱 #bash #linux2 521
Аудит переменной
$PATH: поиск небезопасных директорий и дубликатов
Переменная $PATH определяет, где shell ищет исполняемые файлы. Один лишний каталог - и вместо системной утилиты может запуститься совсем другая программа.
Именно поэтому $PATH стоит периодически проверять.
▪️Посмотреть порядок поиска
echo "$PATH" | tr ':' '\n'
Shell просматривает каталоги сверху вниз. Если команда встречается в нескольких местах, будет использована первая найденная.
▪️Поиск дубликатов
Повторяющиеся каталоги не ломают систему, но замедляют поиск команд и усложняют отладку:
echo "$PATH" | tr ':' '\n' | sort | uniq -d
Если вывод не пустой - есть дубликаты.
▪️Опасные записи
Особое внимание стоит обратить на:
.
./bin
/tmp
/var/tmp
/home/user/bin
Каталог . означает “текущая директория”.
Если он находится в $PATH, достаточно оказаться в папке с вредоносным файлом ls или ssh, чтобы по ошибке запустить его вместо системной утилиты.
▪️Проверка прав доступа
Даже “нормальный” каталог может быть проблемой, если в него могут писать другие пользователи:
find $(echo "$PATH" | tr ':' ' ') \
-maxdepth 0 -perm -0002 -ls 2>/dev/null
World-writable директории в $PATH - серьёзный повод для проверки.
▪️Какая команда будет запущена?
Не всегда очевидно, какой бинарник использует shell:
type -a python
или
which -a python
Это покажет все найденные версии в порядке поиска.
▪️Почему это важно
Ошибки в $PATH могут приводить не только к странному поведению скриптов, но и к компрометации системы. Несколько минут аудита помогут обнаружить небезопасные каталоги, лишние записи и потенциальную подмену исполняемых файлов ещё до того, как это станет проблемой.
BashTex 📱 #bash #linux2 521
shopt: малоизвестные настройки Bash, которые меняют поведение shell
Большинство пользователей знают про set -e или set -u, но в Bash есть ещё один мощный инструмент настройки - shopt.
С его помощью можно включать и отключать десятки дополнительных возможностей оболочки.
▪️Посмотреть доступные опции
shopt
Или только включённые:
shopt -s
▪️globstar - рекурсивный поиск без find
По умолчанию:
ls **/*.log
не сработает.
Включаем:
shopt -s globstar
Теперь:
ls **/*.log
найдёт все .log-файлы во вложенных каталогах.
▪️nullglob - если файлов нет
Без этой опции:
for file in *.log; do
echo "$file"
done
выведет:
*.log
Вместо пустого списка.
Исправляем:
shopt -s nullglob
Теперь цикл просто не выполнится.
▪️dotglob - учитывать скрытые файлы
По умолчанию * не включает файлы, начинающиеся с точки.
После:
shopt -s dotglob
они тоже попадут в результат.
▪️failglob - защита от опечаток
Если шаблон не совпал ни с одним файлом:
rm *.bak
с failglob Bash сразу сообщит об ошибке вместо передачи шаблона команде.
shopt -s failglob
Это помогает избежать неожиданных сценариев в автоматизации.
▪️Почему это важно
Несколько опций shopt способны заметно изменить поведение Bash без переписывания скриптов. Особенно полезны globstar, nullglob и failglob - они делают работу с шаблонами более удобной и предсказуемой.
BashTex 📱 #bash #linux2 521
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 #linux2 521
Анализ активных 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 #linux2 521
📘 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
2 521
Скрипт поиска процессов с аномальным потреблением памяти
Когда на сервере заканчивается память, первое желание - открыть
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 #linux2 521
Проверка файловых систем, смонтированных с опасными опциями
При аудите 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 #linux2 521
Автоматическая реакция на 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 #linux2 521
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 #linux2 521
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 #scripts2 521
Подготовка к DevOps/SRE интервью с «Troubleshooting Docker и Kubernetes: поиск и устранение проблем»
В программе только важные аспекты:
— troubleshooting Docker и образов
— диагностика сетевых проблем
— настройка readiness/liveness probes
— отладка pod’ов, деплоев и ingress
— анализ логов контейнеров и кластера
— разбор ошибок CrashLoopBackOff, OOMKilled, ImagePullBackOff и других
Собеседования на DevOps/SRE сейчас всё чаще строятся вокруг реальных инцидентов. Данный курс фокусируется именно на таких сценариях и помогает в подготовке к практическим вопросам
48 часов доступен со скидкой 25%
↗️ Пройти курс на Stepik
2 521
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 #linux2 521
Работа с дескрипторами файлов через
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 #linux2 521
Проверка недавно созданных пользователей: 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 #du2 521
Почему
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