Процеси та systemd

Процеси в Linux

Що таке процес?

Процес — це запущена програма з власним адресним простором, ресурсами та станом.

┌─────────────────────────────────────────────────────────────────┐
│  Ієрархія процесів                                              │
│                                                                 │
│  systemd (PID 1)                                                │
│  ├── sshd                                                       │
│  │   └── sshd (session)                                         │
│  │       └── bash                                               │
│  │           └── vim                                            │
│  ├── nginx                                                      │
│  │   ├── nginx (worker)                                         │
│  │   └── nginx (worker)                                         │
│  └── dockerd                                                    │
│      └── containerd                                             │
│                                                                 │
│  Кожен процес має:                                              │
│  • PID (Process ID)                                             │
│  • PPID (Parent Process ID)                                     │
│  • UID/GID (User/Group)                                         │
│  • Стан (Running, Sleeping, Zombie...)                          │
│  • Пріоритет (nice value)                                       │
└─────────────────────────────────────────────────────────────────┘

Стани процесів

┌─────────────────────────────────────────────────────────────────┐
│  R (Running)    — виконується на CPU                            │
│  S (Sleeping)   — чекає на I/O або подію                        │
│  D (Disk sleep) — неперервний сон (I/O)                         │
│  Z (Zombie)     — завершений, чекає на батька                   │
│  T (Stopped)    — зупинений (Ctrl+Z або SIGSTOP)               │
│  I (Idle)       — kernel thread                                 │
└─────────────────────────────────────────────────────────────────┘

Перегляд процесів

# Базовий список
ps aux
# a = всіх користувачів
# u = user-oriented format
# x = процеси без терміналу

# Ієрархія (дерево)
ps auxf
pstree
pstree -p  # з PID

# Конкретний процес
ps aux | grep nginx
pgrep nginx
pgrep -l nginx  # з іменами

# Детальна інформація
ps -p 1234 -o pid,ppid,cmd,stat,%cpu,%mem

# top / htop
top
htop  # інтерактивний, рекомендовано

htop shortcuts

┌─────────────────────────────────────────────────────────────────┐
│  F1 - Help                                                      │
│  F2 - Setup                                                     │
│  F3 - Search                                                    │
│  F4 - Filter                                                    │
│  F5 - Tree view                                                 │
│  F6 - Sort by                                                   │
│  F7 - Nice - (зменшити пріоритет)                              │
│  F8 - Nice + (збільшити пріоритет)                             │
│  F9 - Kill                                                      │
│  F10 - Quit                                                     │
│                                                                 │
│  Space - Tag process                                            │
│  U - Untag all                                                  │
│  k - Kill selected                                              │
│  t - Tree view toggle                                           │
└─────────────────────────────────────────────────────────────────┘

Сигнали

Основні сигнали

Сигнал Номер Опис Можна перехопити?
SIGHUP 1 Hangup (reload config) Так
SIGINT 2 Interrupt (Ctrl+C) Так
SIGQUIT 3 Quit (Ctrl+\) Так
SIGKILL 9 Kill (примусово) НІ
SIGTERM 15 Terminate (graceful) Так
SIGSTOP 19 Stop (Ctrl+Z) НІ
SIGCONT 18 Continue Так
SIGUSR1 10 User defined 1 Так
SIGUSR2 12 User defined 2 Так

Надсилання сигналів

# kill — не тільки для "вбивання"
kill PID            # SIGTERM (15) — graceful
kill -9 PID         # SIGKILL — force
kill -15 PID        # SIGTERM
kill -HUP PID       # SIGHUP — reload
kill -STOP PID      # SIGSTOP — pause
kill -CONT PID      # SIGCONT — resume

# killall — за іменем
killall nginx
killall -9 nginx

# pkill — за паттерном
pkill nginx
pkill -f "python script.py"  # по командному рядку
pkill -u username            # всі процеси користувача

# Список сигналів
kill -l

SIGTERM vs SIGKILL

┌─────────────────────────────────────────────────────────────────┐
│  SIGTERM (15) — рекомендований спосіб                          │
│  • Процес може перехопити сигнал                               │
│  • Зберегти дані                                                │
│  • Закрити з'єднання                                           │
│  • Завершитися коректно                                        │
│                                                                 │
│  SIGKILL (9) — крайній захід                                   │
│  • Ядро миттєво завершує процес                                │
│  • Процес НЕ МОЖЕ перехопити                                   │
│  • Можлива втрата даних                                        │
│  • Ресурси можуть не звільнитися                               │
│                                                                 │
│  Правильний порядок:                                            │
│  1. kill PID (SIGTERM)                                         │
│  2. Почекати кілька секунд                                     │
│  3. Якщо не завершився: kill -9 PID                            │
└─────────────────────────────────────────────────────────────────┘

Nice та пріоритети

# nice value: -20 (highest priority) to +19 (lowest)
# Тільки root може встановлювати негативні значення

# Запустити з низьким пріоритетом
nice -n 10 ./heavy_script.sh

# Змінити пріоритет запущеного процесу
renice -n 5 -p 1234
renice -n 10 -u username  # всі процеси користувача

# Переглянути nice value
ps -o pid,ni,cmd -p 1234

Фонові процеси та jobs

# Запустити у фоні
./script.sh &

# Перенести в фон (Ctrl+Z, потім bg)
./script.sh
# Ctrl+Z
bg

# Переглянути jobs
jobs

# Повернути на передній план
fg %1

# Продовжити у фоні
bg %1

# Запустити процес, який переживе logout
nohup ./script.sh &
# Output в nohup.out

# Або з disown
./script.sh &
disown

# Краще використовувати tmux/screen для long-running tasks

systemd

Архітектура

┌─────────────────────────────────────────────────────────────────┐
│                         systemd                                 │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │ systemctl — управління сервісами                        │    │
│  │ journalctl — перегляд логів                             │    │
│  │ hostnamectl — hostname                                  │    │
│  │ timedatectl — час та timezone                           │    │
│  │ loginctl — сесії користувачів                           │    │
│  │ systemd-analyze — аналіз завантаження                   │    │
│  └─────────────────────────────────────────────────────────┘    │
│                                                                 │
│  Unit Types:                                                    │
│  .service  — сервіси (демони)                                  │
│  .socket   — socket activation                                  │
│  .target   — групи units (аналог runlevels)                    │
│  .timer    — scheduled tasks (аналог cron)                     │
│  .mount    — точки монтування                                   │
│  .path     — file system paths (inotify)                       │
│  .device   — пристрої                                           │
│  .slice    — cgroups ієрархія                                   │
└─────────────────────────────────────────────────────────────────┘

systemctl — основні команди

# Статус сервісу
systemctl status nginx
systemctl status nginx.service  # повна назва

# Запустити/зупинити/перезапустити
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl reload nginx    # перечитати конфіг без restart

# Увімкнути/вимкнути автозапуск
systemctl enable nginx
systemctl disable nginx
systemctl enable --now nginx  # enable + start

# Перевірити чи enabled
systemctl is-enabled nginx

# Перевірити чи active
systemctl is-active nginx

# Список всіх сервісів
systemctl list-units --type=service
systemctl list-units --type=service --state=running
systemctl list-units --type=service --state=failed

# Список unit файлів
systemctl list-unit-files --type=service

# Показати залежності
systemctl list-dependencies nginx

# Перезавантажити конфігурацію systemd
systemctl daemon-reload

Unit файли

# Розташування:
# /lib/systemd/system/     — системні units (пакети)
# /etc/systemd/system/     — локальні/override units
# /run/systemd/system/     — runtime units

# Переглянути unit файл
systemctl cat nginx.service

# Редагувати unit (створює override)
systemctl edit nginx.service

# Редагувати повний unit файл
systemctl edit --full nginx.service

Структура .service файлу

# /etc/systemd/system/myapp.service

[Unit]
Description=My Application
Documentation=https://example.com/docs
After=network.target postgresql.service
Requires=postgresql.service
Wants=redis.service

[Service]
Type=simple
User=appuser
Group=appgroup
WorkingDirectory=/opt/myapp
Environment=NODE_ENV=production
EnvironmentFile=/etc/myapp/env
ExecStartPre=/opt/myapp/pre-start.sh
ExecStart=/opt/myapp/start.sh
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/opt/myapp/stop.sh
Restart=on-failure
RestartSec=5
TimeoutStartSec=30
TimeoutStopSec=30

# Security
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Секції Unit файлу

┌─────────────────────────────────────────────────────────────────┐
  [Unit]  метадані та залежності                               
  Description=  Опис сервісу                                    
  After=        Запустити після (ordering)                      
  Before=       Запустити перед                                 
  Requires=     Обов'язкові залежності                          │
│  Wants=        Бажані залежності (не критичні)                 │
│  Conflicts=    Конфліктуючі units                              │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│  [Service] — як запускати сервіс                               │
│  Type=         simple|forking|oneshot|notify|dbus              │
│  ExecStart=    Команда запуску                                 │
│  ExecStop=     Команда зупинки                                 │
│  ExecReload=   Команда reload                                  │
│  Restart=      no|always|on-success|on-failure|on-abnormal     │
│  RestartSec=   Затримка перед restart                          │
│  User=/Group=  Від якого користувача запускати                 │
│  Environment=  Змінні оточення                                 │
│  WorkingDirectory= Робоча директорія                           │
│                                                                 │
├─────────────────────────────────────────────────────────────────┤
│  [Install] — як встановлювати (enable)                         │
│  WantedBy=     До якого target прив'язати                      
  RequiredBy=   Обов'язково для target                          
  Alias=        Альтернативні імена                             
└─────────────────────────────────────────────────────────────────┘

Service Types

# Type=simple (default)
# Процес запускається напряму, PID=main process

# Type=forking
# Процес форкається, батько завершується
# Потрібно вказати PIDFile=

# Type=oneshot
# Короткий процес, завершується після виконання
# RemainAfterExit=yes щоб вважався active

# Type=notify
# Процес сповіщає systemd про готовність через sd_notify()

# Type=dbus
# Процес реєструється на D-Bus

Приклад: власний сервіс

# /etc/systemd/system/myapi.service
[Unit]
Description=My REST API
After=network.target

[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/api
ExecStart=/usr/bin/python3 app.py
Restart=always
RestartSec=3

[Install]
WantedBy=multi-user.target
# Застосувати
systemctl daemon-reload
systemctl enable --now myapi
systemctl status myapi

journalctl — системні логи

# Всі логи
journalctl

# Логи конкретного сервісу
journalctl -u nginx
journalctl -u nginx.service

# Follow (як tail -f)
journalctl -f
journalctl -fu nginx

# Останні N рядків
journalctl -n 100
journalctl -n 50 -u nginx

# За часом
journalctl --since "2026-01-17 10:00"
journalctl --since "1 hour ago"
journalctl --since today
journalctl --since yesterday --until today

# За пріоритетом (0-7)
journalctl -p err      # error і вище
journalctl -p warning  # warning і вище
# emerg=0, alert=1, crit=2, err=3, warning=4, notice=5, info=6, debug=7

# Kernel messages
journalctl -k
journalctl --dmesg

# Цього завантаження
journalctl -b
journalctl -b -1  # попереднього завантаження

# JSON output
journalctl -o json-pretty

# Disk usage
journalctl --disk-usage

# Очистити старі логи
journalctl --vacuum-time=7d   # старші 7 днів
journalctl --vacuum-size=500M # обмежити до 500MB

Налаштування journald

# /etc/systemd/journald.conf

[Journal]
Storage=persistent      # auto, volatile, persistent, none
Compress=yes
SystemMaxUse=500M       # максимальний розмір
SystemMaxFileSize=50M   # максимальний розмір одного файлу
MaxRetentionSec=1month  # зберігати місяць
MaxFileSec=1day         # ротація щодня

Targets (Runlevels)

# Targets замінили runlevels

# Поширені targets:
# poweroff.target    — halt (runlevel 0)
# rescue.target      — single user (runlevel 1)
# multi-user.target  — multi-user, no GUI (runlevel 3)
# graphical.target   — multi-user, GUI (runlevel 5)
# reboot.target      — reboot (runlevel 6)

# Поточний target
systemctl get-default

# Змінити default target
systemctl set-default multi-user.target

# Перейти до target зараз
systemctl isolate rescue.target
systemctl isolate multi-user.target

Timers (замість cron)

Створення timer

# /etc/systemd/system/backup.service
[Unit]
Description=Daily backup

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily

[Timer]
OnCalendar=daily          # або конкретний час
# OnCalendar=*-*-* 02:00:00
# OnCalendar=Mon *-*-* 09:00:00
Persistent=true           # запустити пропущені

[Install]
WantedBy=timers.target
# Увімкнути timer
systemctl enable --now backup.timer

# Список timers
systemctl list-timers

# Статус
systemctl status backup.timer

OnCalendar синтаксис

# Формат: DayOfWeek Year-Month-Day Hour:Minute:Second

minutely        → *-*-* *:*:00
hourly          → *-*-* *:00:00
daily           → *-*-* 00:00:00
weekly          → Mon *-*-* 00:00:00
monthly         → *-*-01 00:00:00
yearly          → *-01-01 00:00:00

# Приклади:
*-*-* 02:00:00           # Кожного дня о 2:00
Mon,Fri *-*-* 10:00:00   # Пн та Пт о 10:00
*-*-* *:00,30:00         # Кожні 30 хвилин
*-*-1,15 00:00:00        # 1-го та 15-го числа

# Перевірити синтаксис
systemd-analyze calendar "Mon *-*-* 10:00"

Аналіз завантаження

# Час завантаження
systemd-analyze

# Детально по units
systemd-analyze blame

# Критичний шлях
systemd-analyze critical-chain

# Візуалізація (SVG)
systemd-analyze plot > boot.svg

# Перевірити unit файл
systemd-analyze verify /etc/systemd/system/myapp.service

Troubleshooting systemd

# Сервіс не запускається
systemctl status myapp.service
journalctl -u myapp.service -n 50 --no-pager

# Перевірити синтаксис unit файлу
systemd-analyze verify myapp.service

# Перезавантажити конфігурацію
systemctl daemon-reload

# Скинути failed state
systemctl reset-failed

# Залежності
systemctl list-dependencies myapp.service
systemctl list-dependencies --reverse myapp.service

# Що блокує shutdown
systemd-analyze blame
systemctl list-jobs

Типові проблеми та рішення

Проблема Причина Рішення
Service failed Помилка в ExecStart journalctl -u service
Start timeout Процес не запускається Перевірити Type=, збільшити TimeoutStartSec
Zombie processes Батько не обробляє SIGCHLD Виправити код або використати init
High load Runaway process top/htop, kill, перевірити логіку
Changes not applied Не виконано daemon-reload systemctl daemon-reload
Service restarts Restart=always Перевірити exit code, логи

Підсумок

Управління процесами:

ps aux                    # Список процесів
htop                      # Інтерактивний моніторинг
kill -15 PID             # Graceful termination
kill -9 PID              # Force kill (крайній захід)

systemd:

systemctl status service  # Статус
systemctl start/stop     # Запуск/зупинка
systemctl enable         # Автозапуск
journalctl -u service    # Логи
systemctl daemon-reload  # Перезавантажити конфіг

Див. також

Шлях: getting-started/processes-systemd.md

UMTC Wiki © 2026 | Ukrainian Military Tactical Communications