ps: смотрим на процессы
ps (process status) — главный инструмент, чтобы увидеть, что сейчас работает в системе. Это снапшот — выводит состояние процессов на момент запуска и завершается. Если нужно «смотреть как меняется» — это top/htop из следующего урока, а ps — для «отчёт прямо сейчас, в логи положить, проанализировать grep-ом».
У ps есть исторический подвох: два разных синтаксиса флагов — BSD-стиль (без дефиса) и System V-стиль (с дефисом). Они одновременно работают и иногда смешиваются. Разберёмся.
Две вселенные ps: BSD vs System V
В мире UNIX исторически было два семейства: BSD (Berkeley) и System V (AT&T). У них были разные ps с разными флагами. Linux объединил оба варианта в одной утилите, поэтому вы видите такое:
Один и тот же тул, два стиля флагов. Можно использовать любой
Запомните хотя бы один стиль. Большинство DE/DevOps используют ps aux — это идиоматично и встречается в любом туториале с Stack Overflow.
# BSD-стиль: все процессы со всех пользователей, user-oriented
ps aux
# System V-стиль: все процессы, full format
ps -ef
Вывод ps aux:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 168528 12384 ? Ss May01 0:12 /sbin/init
root 432 0.0 0.0 72340 4992 ? Ss May01 0:00 /usr/sbin/sshd
postgres 1300 0.5 2.1 245680 87232 ? S May01 8:23 postgres
levo 2500 0.0 0.1 21560 9024 pts/0 Ss 10:15 0:00 -bash
levo 3300 0.2 0.5 84320 22340 pts/0 R+ 10:42 0:00 ps aux
Колонки ps aux — что значат
Что показывает каждое поле в стандартном aux-выводе
Различие VSZ vs RSS — частый вопрос на собеседовании. VSZ (virtual size) включает всё «обещанное» — все mmap, swap, библиотеки. RSS (resident set size) — только реально занятое в физической RAM. Когда нужно понять «сколько процесс ест памяти на самом деле» — смотрите RSS, а не VSZ.
STAT — модификаторы состояния
В колонке STAT иногда видно Ss+, Sl, R<, D<. Первая буква — основное состояние (R/S/D/Z/T), дальше — модификаторы:
+ foreground process group (привязан к терминалу как foreground)
s session leader (управляет терминальной сессией)
l multi-threaded (имеет threads)
< high priority (низкий nice value)
N low priority (высокий nice value)
L pages locked in memory (используется mlock)
Например, Ss+ у bash значит: Sleeping, session leader, foreground. Sl у postgres значит: Sleeping, multi-threaded (хотя Postgres использует процессы, не threads — но есть internal threads тоже).
Детально по конкретному PID
# Детали по PID 1234
ps -fp 1234
# Или BSD-стиль
ps u -p 1234
# Конкретные колонки (наш контроль)
ps -p 1234 -o pid,ppid,user,%cpu,%mem,etime,cmd
-o позволяет выбирать колонки. Полезные:
Кастомизация вывода ps под задачу
Фильтрация и сортировка
# Сортировка по убыванию использования памяти
ps aux --sort=-%mem | head
# Сортировка по убыванию CPU
ps aux --sort=-%cpu | head
# Сортировка по PID (по возрастанию)
ps aux --sort=pid
# Несколько критериев: сначала по user, потом по %mem убывание
ps aux --sort=user,-%mem
Минус в --sort=-%mem — это «по убыванию». Без минуса — по возрастанию.
# Только процессы конкретного пользователя
ps -u postgres
# Только процессы по конкретному терминалу
ps -t pts/0
# Только с конкретным PPID (например, все потомки systemd)
ps --ppid 1 | head
Анатомия процесса: что хранит ядро для каждого процесса
pgrep и pkill — найти/убить по имени
pgrep ищет процессы по имени или паттерну. pkill тоже ищет, но сразу шлёт сигнал.
# PID-ы всех процессов с airflow в имени
pgrep airflow
# То же, но с дополнительной информацией: PID + cmdline
pgrep -af airflow
# Точное совпадение
pgrep -x bash
# Конкретного пользователя
pgrep -u airflow
# Убить (TERM = SIGTERM = 15)
pkill airflow
# Жёстко (SIGKILL = 9)
pkill -9 airflow
# Убить конкретного пользователя
pkill -u airflow -9
pkill airflow убьёт все процессы с подстрокой «airflow» в имени, включая ваш vim airflow_dag.py, если кто-то так назвал файл. Перед pkill всегда делайте pgrep -af чтобы увидеть, кого именно убьёте.
DE-сценарий: после деплоя нужно перезапустить Airflow scheduler.
# 1. Сначала посмотри, что найдётся
pgrep -af "airflow scheduler"
# 2. Аккуратно прибей (TERM, не KILL)
pkill -f "airflow scheduler"
# 3. Подожди немного, проверь
sleep 3
pgrep -af "airflow scheduler" # если ещё работает — sigkill
-f означает «искать по полной командной строке», не только по имени процесса. Это нужно для случаев, когда имя процесса — python, но командная строка — python /opt/airflow/bin/airflow scheduler.
/proc/PID/ — внутренности процесса
Уже видели в уроке 01. Теперь — на практике для DE.
# Куда process пишет stdout (например, Airflow worker)
ls -l /proc/$(pgrep -f "airflow worker")/fd/1
# Текущая рабочая директория процесса
ls -l /proc/$(pgrep -x postgres)/cwd
# Все переменные окружения (например, AIRFLOW__CORE__*)
cat /proc/$(pgrep -x scheduler)/environ | tr '\0' '\n' | grep AIRFLOW
# Memory usage детально
cat /proc/$(pgrep -x postgres)/status | grep -E "VmRSS|VmSize|Threads"
# Открытые сетевые сокеты
ls -l /proc/$(pgrep -x postgres)/fd/ | grep socket
DE-сценарии
1. «Кто-то жрёт всю память на сервере»
# Топ-10 по памяти
ps aux --sort=-%mem | head
# Если занят суммарно много — посмотри по группам процессов
ps -eo rss,user,cmd --sort=-rss | awk '{a[$2]+=$1} END {for (u in a) print a[u], u}' | sort -rn | head
2. «Когда был запущен Airflow scheduler?»
# etime — прошедшее время с запуска
ps -p $(pgrep -x airflow-scheduler) -o pid,etime,start,cmd
# Или дата старта в полном формате
ps -p $(pgrep -x airflow-scheduler) -o lstart,pid,cmd
3. «Сколько worker-ов Airflow сейчас работает?»
pgrep -c -f "airflow worker"
# Просто число
4. «Что висит в D (uninterruptible) — потенциальный disk issue»
ps aux | awk '$8 ~ /D/ {print}'
Если их много — проблема с диском, NFS или iSCSI mount.
5. «Есть ли зомби?»
ps aux | awk '$8 ~ /Z/'
# Если есть — нужно идти по PPID и чинить родителя
ps + grep — частая ошибка
Классика:
ps aux | grep airflow
В вывод попадёт сам процесс grep airflow — он же содержит «airflow» в команде! Чтобы исключить:
# Способ 1: квадратные скобки — grep не матчит сам себя
ps aux | grep '[a]irflow'
# Способ 2: ещё один grep
ps aux | grep airflow | grep -v grep
# Способ 3 (лучший): pgrep
pgrep -af airflow
[a]irflow — регулярка, которая в результирующих строках выводит «airflow», но в самой регулярке стоит [a]irflow. Соответственно grep сам себя не находит. Старый трюк, но работает.
Попробуй сам
# 1. Топ-5 процессов по памяти
ps aux --sort=-%mem | head -6
# 2. Топ-5 процессов по CPU
ps aux --sort=-%cpu | head -6
# 3. Все процессы под твоим пользователем
ps -u $USER -o pid,etime,cmd
# 4. Запусти sleep и посмотри его внутренности
sleep 300 &
SPID=$!
ls -l /proc/$SPID/cwd
ls -l /proc/$SPID/fd/
cat /proc/$SPID/status | head -20
# Прибей
kill $SPID
# 5. Сколько процессов в системе всего
ps -e --no-headers | wc -l
# 6. Сколько из них спят
ps -eo stat --no-headers | awk '$1 ~ /^S/' | wc -l
Cross-link: про сортировку текста — модуль 7. Про awk-обработку вывода ps — модуль 8. Про top/htop (live мониторинг) — следующий урок 03.