Зачем 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 - что показывает
$ 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 или runnableS- 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 leaderl- multi-threaded+- foreground в его group<- high priority (nice < 0)N- low priority (nice > 0)L- есть locked pages
Пример: Ssl+ - session leader, спит, многопоточный, foreground.
ps -ef - чуть другой набор
$ 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 - кастомный формат
Самый мощный режим. Колонки списком через запятую:
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 (минус = по убыванию):
ps -eo pid,user,pcpu,pmem,cmd --sort=-pcpu | head
Тред-вью
По дефолту ps показывает только процессы. Для threads:
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
ps -ef --forest # ASCII-дерево
ps auxf
pstree -p # отдельная утилита, чище
pstree -psaT 1 # дерево с PID и cmdline
Часто используемые сценарии
# Топ-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- искать/убивать по имени или паттерну cmdlinepidof- PID по точному имени бинарника/proc/$PID/status- читать данные одного процесса напрямуюtop/[[cmd-htop|htop]] - интерактивно