Процессы и ps
Каждая запущенная программа — это процесс с PID и PPID, образующие дерево с корнем в init. ps aux и ps -ef дают два вида таблицы процессов: первый ориентирован на пользователя, второй показывает полные командные строки и отношения родитель-потомок.
Когда ты вводишь команду и нажимаешь Enter, оболочка не выполняет её напрямую — она делает fork дочернего процесса. Этот дочерний процесс наследует копию файловых дескрипторов и окружения оболочки, затем вызывает exec, чтобы заменить себя указанной программой. Этот шаблон fork-exec — способ существования каждого процесса в Linux, кроме PID 1 (init/systemd), который ядро запускает напрямую.
В результате получается дерево: PID 1 в корне, всё остальное — ниже. Понимание этого дерева — кто кого породил, какие процессы потребляют ресурсы, какие осиротели или зависли — является основой для всех задач с сигналами, управлением задачами и мониторингом в этом юните.
После этого урока ты сможешь читать вывод ps aux по столбцам, использовать ps -ef для трассировки отношений родитель-потомок через PPID, различать фоновые и фронтальные процессы, идентифицировать зомби и сироты, и обращаться к /proc/<PID> за сырыми данными ядра.
Каждый процесс имеет PID (идентификатор процесса) и PPID (идентификатор родительского процесса). Ядро присваивает PID последовательно. PID 1 — всегда init или systemd. Все остальные процессы являются потомками: твоя оболочка — дочерний процесс сессии входа; каждая команда, которую ты запускаешь, — дочерний процесс твоей оболочки.
Когда родитель завершается раньше своих детей, те дети перепривязываются к PID 1 — они становятся сиротами, усыновлёнными init. Когда дочерний процесс завершается, но родитель ещё не вызвал wait() для получения кода завершения, дочерний процесс остаётся в таблице процессов как зомби (состояние Z). Зомби не удерживают ресурсов, кроме слота в таблице, но их большое количество указывает на ошибку в родительском процессе.
echo $$ # PID текущей оболочки
echo $PPID # PID родителя оболочкиps aux — снимок всех процессов в BSD-стиле. Столбцы, которые нужно читать свободно:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 22516 9216 ? Ss Jun20 0:03 /sbin/init
alice 1843 0.3 0.5 102400 41200 pts/0 S+ 10:12 0:00 vim notes.txt
alice 1901 98.0 1.2 204800 102400 pts/1 R 10:15 0:42 python train.py- VSZ — размер виртуальной памяти (включает разделяемые библиотеки, mmap-файлы; часто велик и вводит в заблуждение)
- RSS — резидентный размер (страницы, реально находящиеся в ОЗУ прямо сейчас; важен для давления на память)
- STAT — состояние процесса:
Rвыполняется,Sспит (прерываемый),Dнеперываемое ожидание I/O,Zзомби,Tостановлен. Суффикс+означает группу переднего плана;s— лидер сессии;l— многопоточный. - TTY — управляющий терминал;
?означает отсутствие терминала (демон). - TIME — накопленное время CPU, не реальное время.
ps aux
ps aux | grep nginx # фильтровать по "nginx"
ps aux --sort=-%mem | head # топ-10 по памятиps -ef в POSIX-стиле явно добавляет PPID. Используй его для трассировки отношений родитель-потомок.
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Jun20 ? 00:00:03 /sbin/init
root 512 1 0 Jun20 ? 00:00:00 /usr/sbin/sshd -D
alice 1801 512 0 10:11 pts/0 00:00:00 -bash
alice 1843 1801 0 10:12 pts/0 00:00:00 vim notes.txtЧитай так: sshd (512) порождён init (1). Твой bash (1801) порождён sshd (512). vim (1843) порождён bash (1801).
ps -ef
ps -ef | grep <PID> # найти родителя конкретного процесса
ps -ef --forest # ASCII-дерево (GNU ps)
pstree -p # графическое дерево с PIDПередний план против фона. Процесс на переднем плане привязан к группе процессов управляющего терминала — он получает клавиатурные сигналы (Ctrl-C отправляет SIGINT, Ctrl-Z отправляет SIGTSTP) и блокирует приглашение. Фоновый процесс помещён в другую группу процессов и не блокирует приглашение.
В выводе ps aux STAT, заканчивающийся на +, указывает процесс на переднем плане. STAT без + (при установленном TTY) — фоновая задача. STAT с ? в TTY — демон без терминала.
Это различие важно: сигналы с клавиатуры идут только в группу процессов переднего плана. Для взаимодействия с фоновым процессом нужно обращаться к нему по PID или использовать команды управления задачами (урок 03).
/proc/<PID> даёт сырые данные ядра для любого живого процесса. Каждый PID получает каталог в виртуальной файловой системе /proc:
cat /proc/1843/status # состояние, память, UID, GID
cat /proc/1843/cmdline | tr '\0' ' ' # полная командная строка (NUL-разделители)
ls -la /proc/1843/fd # открытые файловые дескрипторы
cat /proc/1843/maps # карта виртуальной памяти/proc — не диск, это интерфейс ядра, генерирующий содержимое при чтении. Это источник истины, из которого читают ps, top и lsof. Когда нужно что-то, что ps не показывает, обращайся прямо к /proc.
Найти пожирателя памяти на продакшн-сервере.
ps aux --sort=-%mem | head -10Вывод (сокращён):
USER PID %CPU %MEM RSS COMMAND
postgres 3412 2.1 18.4 1.5G postgres: autovacuum worker
node 4102 0.8 12.3 1.0G node /app/server.js
redis 1234 0.1 6.2 512M redis-server *:6379Воркер autovacuum PostgreSQL занимает 18% ОЗУ. Следующий шаг: проверить /proc/3412/status для детальной разбивки памяти и ps -ef | grep 3412, чтобы убедиться, что это дочерний процесс основного процесса postgres (ожидаемо), а не что-то неожиданное.
# Подтвердить родство
ps -ef | awk '$2==3412 || $3==3412'▸Почему это работает
На macOS и BSD нет файловой системы /proc. ps на macOS использует BSD-флаги (ps aux работает, но -ef ведёт себя иначе — ps -ef на macOS по умолчанию показывает только твои процессы). pstree не установлен по умолчанию (установи через Homebrew: brew install pstree). Для работы с Linux эти различия не важны; описанные инструменты работают одинаково на любой современной Linux-системе.
▸Частая ошибка
%CPU в ps aux — не мгновенное использование процессора, а процент времени CPU, потреблённый за всё время жизни процесса. Процесс, работавший на полную мощность 10 минут назад, но сейчас простаивающий, всё равно покажет высокий %CPU. Для реального использования процессора в реальном времени используй top или htop (урок 04), которые показывают скользящее среднее за недавний период.
Процесс показывает STAT 'Z' в выводе ps aux. Что это означает?
Каждый процесс имеет PID и PPID, образующие дерево с корнем в PID 1. ps aux даёт снимок процессов со столбцами памяти, CPU и состояния; ps -ef добавляет столбец PPID для трассировки родителей. Ключевые коды STAT: R выполняется, S спит, D неперываемый, T остановлен, Z зомби. Процесс на переднем плане находится в активной группе процессов терминала (STAT заканчивается на +); фоновый — в другой группе. /proc/<PID> предоставляет сырые данные ядра, которые читают все инструменты мониторинга.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.