# ps - снимок процессов _Команды · LinuxLab Knowledge Base_ **TL;DR:** ps - снимок процессов в момент вызова. Два диалекта: BSD (`aux`, без дефиса) и UNIX (`-ef`, с дефисом). `-o` задаёт колонки. Для непрерывного просмотра - [[cmd-htop|htop]]. ## Зачем ps Когда нужен **одноразовый** список процессов в скрипт, в pipe, в логи - `ps` идеален. Для интерактивного - [[cmd-htop|htop]]. Для отдельного процесса - `top -p PID` или `cat /proc/PID/status`. ps читает `/proc/*/stat`, `cmdline`, `status` - то же что и htop, но одним кадром. ## Два диалекта - почему так больно Исторически: - **BSD-стиль**: `ps aux` (БЕЗ дефиса) - короткие однобуквенные опции - **UNIX-стиль**: `ps -ef` (С дефисом) - System V Современный `procps-ng` (Linux) принимает оба, плюс `ps --GNU` (с двойным дефисом). Но смешивать опции из разных стилей в одном вызове - источник багов: ``` ps -aux ← UNIX -a + парсится как BSD `aux`. Часто работает, но не гарантировано (разные ps это интерпретируют по-разному). ``` Запомнить: либо `ps aux`, либо `ps -ef`. ## ps aux - что показывает ```bash $ ps aux | head -3 USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.1 168740 11252 ? Ss Apr01 0:23 /sbin/init root 2 0.0 0.0 0 0 ? S Apr01 0:00 [kthreadd] ``` Колонки: | Колонка | Что | |---------|-----| | USER | владелец | | PID | id процесса | | %CPU | средне с момента старта (не realtime!) | | %MEM | RSS / total RAM | | VSZ | virtual size в KiB (включая mmap'ы и не-resident) | | RSS | resident set size в KiB - реально в RAM | | TTY | управляющий терминал; `?` = нет (демон) | | STAT | состояние; см. ниже | | START | когда запущен | | TIME | total CPU time | | COMMAND | argv | ### STAT-флаги - `R` - running или runnable - `S` - interruptible sleep (норма для большинства) - `D` - **uninterruptible sleep** (обычно I/O; не убивается даже SIGKILL) - `T` - stopped (Ctrl-Z, SIGSTOP) - `Z` - zombie (умер, но родитель не reap'нул) - `I` - kernel idle thread (procps-ng 3.3+) Дополнительные флаги: - `s` - session leader - `l` - multi-threaded - `+` - foreground в его group - `<` - high priority (nice < 0) - `N` - low priority (nice > 0) - `L` - есть locked pages Пример: `Ssl+` - session leader, спит, многопоточный, foreground. ## ps -ef - чуть другой набор ```bash $ ps -ef | head -3 UID PID PPID C STIME TTY TIME CMD root 1 0 0 Apr01 ? 00:00:23 /sbin/init root 2 0 0 Apr01 ? 00:00:00 [kthreadd] ``` - **PPID** - parent PID (нет в `ps aux` без `f`) - **C** - CPU utilization - **STIME** - старт - **CMD** - аналог COMMAND Когда нужен PPID - `ps -ef` короче чем `ps -eo pid,ppid,...`. ## -o - кастомный формат Самый мощный режим. Колонки списком через запятую: ```bash ps -eo pid,ppid,user,nice,pri,rss,vsz,stat,wchan,cmd ``` Часто используемые поля: | Поле | Что | |------|-----| | `pid`, `ppid`, `pgid`, `sid` | id'ы | | `user`, `uid`, `group`, `gid` | владельцы | | `nice` (`ni`), `pri` | priority | | `rss`, `vsz`, `pmem` | память | | `pcpu`, `time`, `etime` | CPU и время | | `stat`, `state` | state | | `wchan` | точка в ядре, в которой спит процесс | | `comm`, `cmd`, `args` | имя/argv | | `cgroup` | cgroup-путь (имя systemd-юнита, контейнер) | | `lstart` | абсолютный таймстамп старта | | `tty`, `class`, `policy` | разное | Заголовок переименовать через `=`: `ps -eo pid,user,rss=Memory_KB,cmd`. Сортировка: `--sort=-%cpu` (минус = по убыванию): ```bash ps -eo pid,user,pcpu,pmem,cmd --sort=-pcpu | head ``` ## Тред-вью По дефолту `ps` показывает только процессы. Для threads: ```bash ps -eLf # все threads (-L) с extended-form (-f) ps -T -p $PID # threads конкретного процесса ps -o pid,tid,nlwp,cmd $PID ``` - **PID** - id процесса (TGID в ядре) - **LWP** / **TID** - id треда (PID в ядре) - **NLWP** - сколько threads у процесса ## Tree mode ```bash ps -ef --forest # ASCII-дерево ps auxf pstree -p # отдельная утилита, чище pstree -psaT 1 # дерево с PID и cmdline ``` ## Часто используемые сценарии ```bash # Топ-10 по CPU ps -eo pid,user,pcpu,cmd --sort=-pcpu | head -11 # Топ-10 по памяти ps -eo pid,user,rss,cmd --sort=-rss | head -11 # Все процессы пользователя ps -fu www-data # Сколько живёт процесс ps -o pid,etime,cmd -p $PID # Все zombie ps -eo pid,ppid,stat,cmd | awk '$3 ~ /^Z/' # PIDs nginx (для xargs) pgrep nginx # альтернатива ps + grep pidof nginx ``` Для цикла `pgrep`/`pidof` дешевле и яснее, чем `ps | grep`. ## Когда что-то пошло не так - **`ps aux | grep foo` показывает сам grep** - используй `pgrep foo` или `pgrep -f` (по cmdline). Или `ps aux | grep '[f]oo'`. - **%CPU больше 100** - это **сумма по всем CPU** для multi-thread. Смотри `ps -eL` для per-thread. - **VSZ огромен (TB), RSS маленький** - норма: VSZ включает mmap-region'ы, которые не резидентны. Смотри RSS. - **Не видно argv (`[kworker/...]`)** - kernel thread, нет userspace argv. Скобки = ядерный поток. - **Скрипт обрезает COMMAND** - терминал узкий. `ps -e -ww -o cmd` отключает обрезку. - **`ps` в pipe видит свой PID** - стандарт. Игнорируй или фильтруй. ## Альтернативы - **`pgrep`/`pkill`** - искать/убивать по имени или паттерну cmdline - **`pidof`** - PID по точному имени бинарника - **`/proc/$PID/status`** - читать данные одного процесса напрямую - **`top`/[[cmd-htop|htop]]** - интерактивно ## Команды ```bash ps aux | grep '[s]shd' ``` Все sshd-процессы, без grep'а самого себя - трюк со скобкой ```bash ps -eo pid,user,pcpu,pmem,cmd --sort=-pcpu | head ``` Топ по CPU - типичный one-liner для квика ```bash ps -eo pid,etime,cmd -p $(pgrep -d, nginx) ``` Сколько живут nginx-процессы - elapsed time ```bash ps -ef --forest ``` Все процессы в виде дерева - наглядно кто кого спавнит ```bash ps -o pid,tid,cmd -L -p 1234 ``` Все треды процесса 1234 - LWP/TID ```bash ps -eo pid,cgroup,cmd | grep docker ``` Процессы в Docker-контейнерах (по cgroup-пути) ```bash ps -eo pid,stat,cmd | awk '$2 ~ /Z/' ``` Только zombie - найти потерянных детей ## См. также - [htop - интерактивный монитор процессов](/kb/cmd-htop.md) - [lsof - кто что открыл](/kb/cmd-lsof.md) - [strace - какие syscall'ы делает процесс](/kb/cmd-strace.md) - [Сигналы (SIGTERM, SIGKILL, SIGHUP)](/kb/signals.md) - [Процесс и PID](/kb/process-and-pid.md)