Процессы в Linux: что это такое и какими командами ими управлять

Процессы в Linux: что это такое и какими командами ими управлять Полезное

Процесс в Linux — это запущенный экземпляр программы: ее код, загруженный в память, плюс все, что ядро выделило для работы — номер (PID), собственное адресное пространство, открытые файлы, владелец и приоритет. Программа — файл на диске, процесс — то, что этот файл делает прямо сейчас. Один и тот же файл можно запустить трижды и получить три независимых процесса.

Ниже — как процессы устроены и как ими управлять: посмотреть (ps, top), остановить (kill и сигналы), изменить приоритет (nice, renice), отправить в фон (jobs, bg, fg, nohup). Команды проверены 30.09.2026 в Ubuntu 24.04 (bash 5.2, procps-ng 4.0.4) под обычным пользователем.

Четыре слова, которые путают

  • Программа — исполняемый файл (/usr/bin/sleep). Ресурсов не потребляет, пока не запущена.
  • Процесс — запущенная программа с собственным PID и памятью.
  • Задание (job) — процесс или конвейер процессов, запущенный из текущей оболочки. Номер задания (%1) существует только внутри этого терминала, PID — во всей системе.
  • Сервис (unit) — процесс, который запускает и контролирует systemd, а не терминал.

Еще есть потоки — нити исполнения внутри одного процесса с общей памятью. В этой статье речь про процессы.

Минимальный пример: запустить, увидеть, завершить

Запустим безобидный процесс sleep 300 (ждет 300 секунд и выходит) в фоне и посмотрим на него. Знак & в конце отправляет команду в фон.

sleep 300 &
ps -o pid,ppid,stat,ni,comm

Оболочка печатает номер задания и PID, а ps показывает процессы текущего терминала:

[1] 15
    PID    PPID STAT  NI COMMAND
     11      10 S      0 bash
     15      11 S      0 sleep
     16      11 R+     0 ps

Числа PID у вас будут другими. Что здесь видно:

  • PID — уникальный номер процесса, по нему к процессу обращаются все команды.
  • PPID — номер родителя. У sleep и ps родитель один — оболочка bash с PID 11: новый процесс в Linux порождается уже существующим (кроме самого первого, его запускает ядро). Получается дерево: у пользовательских процессов в корне стоит PID 1 (в большинстве дистрибутивов это systemd).
  • STAT — состояние: sleep спит (S), ps в момент вывода выполняется (R).
  • NI — значение nice, о нем ниже.

Завершим процесс. Переменная $! хранит PID последней фоновой команды, поэтому пример не заденет чужие процессы:

kill $!
jobs
[1]+  Terminated              sleep 300

Как посмотреть процессы: ps, top, htop

ps без аргументов показывает только процессы вашего терминала. Чтобы увидеть всю систему, используют два равноценных варианта: ps -ef (стиль UNIX, есть столбец PPID) и ps aux (стиль BSD, есть доля CPU и памяти).

Процесс из первого примера уже завершен, поэтому запустим новый и найдем его:

sleep 300 &
ps -ef | head -4
pgrep -a sleep
[1] 17
UID          PID    PPID  C STIME TTY          TIME CMD
root           1       0  0 11:47 pts/0    00:00:00 /sbin/docker-init -- bash
root           7       1  0 11:47 pts/0    00:00:00 bash
root          10       7  0 11:47 pts/0    00:00:00 su - ubuntu
17 sleep 300

Прогон шел в контейнере, поэтому PID 1 здесь — docker-init; на обычной машине в первой строке будет systemd. pgrep -a имя ищет процессы по имени и печатает PID с командной строкой — это удобнее, чем ps aux с фильтром через grep. После проверки завершите процесс: kill $!.

Столбец Что означает
UID / USER Владелец процесса
PID, PPID Номер процесса и номер родителя
C, %CPU, %MEM Доля процессорного времени и оперативной памяти
STIME / START Время запуска
TTY Терминал; ? — процесс не привязан к терминалу (типично для сервисов)
TIME Суммарное процессорное время, а не время с момента запуска
CMD / COMMAND Команда с аргументами

top показывает то же в реальном времени: сверху сводка (число задач по состояниям, загрузка CPU, память), ниже список, по умолчанию отсортированный по CPU. Клавиши: M — сортировка по памяти, P — по CPU, k — послать сигнал, q — выход. htop — более наглядный аналог с цветом и деревом процессов; во многих дистрибутивах его нужно ставить отдельным пакетом.

Состояния процесса

Буква в столбце STAT (ps) или S (top) — текущее состояние.

Буква Состояние Что происходит
R running / runnable Выполняется или ждет своей очереди на процессор
S interruptible sleep Ждет события: ввода, таймера, сети. Нормальное состояние большинства процессов
D uninterruptible sleep Ждет ввода-вывода (обычно диск), сигналы пока не обрабатывает
T stopped Приостановлен сигналом, например по Ctrl+Z
Z zombie Завершился, но родитель еще не забрал код возврата
I idle Простаивающий поток ядра

Зомби не занимает память и процессор — от него осталась только запись в таблице процессов. Она исчезает, когда родитель вызывает wait; если родитель завершится, зомби достанется процессу с PID 1, и тот его уберет.

kill и сигналы: как завершить процесс

kill не «убивает», а отправляет процессу сигнал — короткое уведомление, которое доставляет ядро (послать его может и само ядро, и другой процесс). Без указания сигнала уходит SIGTERM (15): вежливая просьба завершиться, процесс успевает сохранить данные и закрыть файлы.

Сигнал Номер Смысл Можно перехватить
SIGTERM 15 Просьба завершиться (по умолчанию у kill) да
SIGINT 2 Прерывание с клавиатуры, Ctrl+C да
SIGHUP 1 Терминал закрыт; сервисы часто перечитывают конфигурацию да
SIGKILL 9 Немедленное уничтожение ядром нет
SIGSTOP 19 Приостановка нет
SIGTSTP 20 Приостановка с клавиатуры, Ctrl+Z да
SIGCONT 18 Продолжить приостановленный да

Номера верны для x86 и ARM; на некоторых архитектурах часть номеров другая, поэтому надежнее писать имена: kill -TERM, kill -KILL.

Правильный порядок — сначала SIGTERM, и только если процесс не реагирует, SIGKILL. Проверим на процессе, который SIGTERM игнорирует:

bash -c 'trap "echo TERM ignored" TERM; while true; do sleep 1; done' &
kill $!
jobs
[1] 21
TERM ignored
[1]+  Running                 bash -c 'trap "echo TERM ignored" TERM; while true; do sleep 1; done' &

Процесс получил сигнал, напечатал сообщение (с задержкой до секунды, когда закончится текущий sleep 1) и продолжил работу. SIGKILL перехватить нельзя:

kill -KILL $!
jobs
[1]+  Killed                  bash -c 'trap "echo TERM ignored" TERM; while true; do sleep 1; done'

Цена SIGKILL — процесс не сохраняет данные, не удаляет временные файлы и не завершает своих потомков: они остаются работать и переходят к PID 1 (или к назначенному процессу-«жнецу»).

Предохранители

  • Перед pkill имя (завершение по имени) посмотрите, что именно попадет под сигнал: pgrep -a имя. Имя сравнивается как шаблон по вхождению, поэтому pkill python заденет и python3, и ipython; точное совпадение задает ключ -x.
  • Обычный пользователь может сигналить только своим процессам. С sudo ограничений нет, поэтому с ним сначала проверяйте владельца и команду: ps -o pid,user,cmd -p PID.
  • PID -1 означает «все процессы, до которых дотянусь»: kill -9 -1 завершит весь ваш сеанс, а от root — почти всю систему. Это не способ «убить зависшую программу».
  • Сервисы останавливают через systemctl, а не kill: иначе systemd может тут же запустить процесс заново.

Приоритеты: nice и renice

Nice — число от -20 до 19, подсказка планировщику: чем оно больше, тем охотнее процесс уступает процессор другим. По умолчанию 0, потомки наследуют значение родителя. На скорость nice влияет, только когда процессора на всех не хватает.

nice запускает команду с нужным значением, renice меняет его у работающего процесса:

nice -n 15 sleep 200 &
ps -o pid,ni,comm
renice -n 19 -p $!
[1] 27
    PID  NI COMMAND
     11   0 bash
     27  15 sleep
     28   0 ps
27 (process ID) old priority 15, new priority 19

Теперь типичная ошибка — попытка вернуть приоритет обратно:

renice -n 0 -p $!
renice: failed to set priority for 27 (process ID): Permission denied

Обычный пользователь может только повышать nice (делать процесс «вежливее»). Понизить значение, в том числе вернуть прежнее, может root: sudo renice -n 0 -p PID. Так система ведет себя при стандартном лимите (ulimit -e показывает 0); если администратор поднял лимит RLIMIT_NICE, пользователь может понижать nice в его пределах. С запуском то же самое: nice -n -5 команда без прав выведет nice: cannot set niceness: Permission denied, но команду все равно запустит — с обычным приоритетом. Перед следующим разделом завершите процесс: kill $!.

Фоновые задачи: jobs, bg, fg, nohup

Команда, запущенная обычным образом, занимает терминал — это передний план. Ее можно приостановить и отправить в фон, не перезапуская:

sleep 600

Нажимаем Ctrl+Z — процесс получает SIGTSTP и останавливается:

^Z
[1]+  Stopped                 sleep 600
bg %1
jobs
fg %1
[1]+ sleep 600 &
[1]+  Running                 sleep 600 &
sleep 600

bg %1 продолжил задание в фоне, jobs показал список заданий этой оболочки, fg %1 вернул задание на передний план — теперь его можно прервать Ctrl+C. Частая ошибка — думать, что Ctrl+Z сразу отправляет в фон: процесс остановлен и ничего не делает, пока не выполнена bg или fg.

Фоновое задание остается привязанным к терминалу: при его закрытии оболочка получает SIGHUP и рассылает его своим заданиям. Чтобы процесс пережил выход, его запускают через nohup и сразу перенаправляют вывод в файл:

nohup sleep 100 > work.log 2>&1 &
jobs
[1] 32
[1]+  Running                 nohup sleep 100 > work.log 2>&1 &

Без перенаправления nohup сам пишет вывод в nohup.out в текущем каталоге (а если туда писать нельзя — в домашнем). После опыта завершите процесс командой kill $! и удалите work.log. Для долгих интерактивных сеансов удобнее tmux, а для постоянно работающих программ — сервис systemd.

Сервисы systemd — кратко

Веб-сервер, база данных, планировщик задач запускаются не из терминала, а менеджером systemd: он стартует их при загрузке, следит за ними и собирает журнал. Раньше такие процессы называли демонами. Управляют ими так (на примере ssh; имя юнита зависит от дистрибутива):

systemctl status ssh
sudo systemctl restart ssh
journalctl -u ssh -n 20

status показывает состояние, главный PID и последние строки журнала; stop, start, restart управляют запуском; enable и disable — автозапуском при загрузке. Команда stop посылает сервису SIGTERM и ждет; если он не завершился за отведенное время, systemd отправляет SIGKILL. Это поведение по умолчанию: сигнал и время ожидания задаются в настройках юнита.

Если не получилось

Симптом Причина Что делать
kill: (PID) - No such process Процесс уже завершился или PID указан неверно Найти актуальный PID: pgrep -a имя
Operation not permitted Процесс принадлежит другому пользователю Проверить владельца; при необходимости sudo kill PID
После kill процесс на месте, STAT = T Остановленный процесс обработает SIGTERM только после продолжения kill -CONT PID или fg
После kill -9 запись осталась, STAT = Z Зомби уже мертв, сигналы на него не действуют Разбираться с родителем (PPID): перезапустить или завершить его
Процесс исчез после закрытия терминала Получил SIGHUP nohup, tmux или сервис systemd
renice: ... Permission denied Понижать nice при стандартных лимитах может только root sudo renice

Выводы

  • Процесс — запущенный экземпляр программы с собственным PID, памятью, владельцем и родителем (PPID); процессы образуют дерево с корнем в PID 1.
  • Смотреть процессы: ps -ef или ps aux — снимок, top и htop — в реальном времени, pgrep -a — поиск по имени.
  • kill отправляет сигнал: по умолчанию SIGTERM (15). SIGKILL (9) — крайняя мера, потому что процесс не успевает ничего сохранить.
  • Nice от -20 до 19: повысить значение может любой пользователь для своих процессов, понизить при стандартных лимитах — только root.
  • &, Ctrl+Z, bg, fg, jobs управляют заданиями текущего терминала; nohup защищает от SIGHUP, а постоянным программам место в сервисах systemd.

Где применяется / связь с практикой

Управление процессами — ежедневная работа администратора: найти, что нагружает сервер, корректно остановить зависшую программу, запустить долгую задачу так, чтобы она пережила обрыв SSH, оформить свое приложение сервисом. Дальше к этому добавляются права, сеть, журналы и автоматизация на bash.

Освойте тему на практике

Системно эти темы разбирают на курсе «Администратор Linux. Базовый уровень». Познакомиться с форматом занятий можно на открытых уроках Otus.

FAQ

Чем kill, pkill и killall отличаются друг от друга?
kill принимает PID или номер задания (%1), pkill и killall — имя процесса. pkill сравнивает имя как шаблон, killall — по точному совпадению; сигнал по умолчанию у всех трех одинаковый — SIGTERM.

Что такое процесс-сирота и чем он отличается от зомби?
Сирота — работающий процесс, чей родитель уже завершился; его усыновляет PID 1 (или назначенный процесс-«жнец»). Зомби, наоборот, уже завершен, а его родитель жив, но еще не забрал код возврата.

Где Linux хранит сведения о процессе?
В виртуальной файловой системе /proc: у каждого процесса есть каталог /proc/PID, например /proc/PID/status содержит имя, состояние и PPID. Именно оттуда читают данные ps и top.

OTUS Журнал
Распродажа ноябрьских курсов (поп-ап)
Бесплатные открытые уроки (поп-ап)