Learning Platform
Глоссарий Troubleshooting
Урок 17.01 · 18 мин
Начальный
capstoneprojectpsshellmonitor/proc

Capstone: три мини-OS-инструмента — что строим и зачем

Вы прошли 14 модулей. От syscalls и kernel ring до vmstat и perf. Знаете, что такое процесс, как fork работает с copy-on-write, почему /proc — это не каталог, а интерфейс к kernel. Теперь нужно собрать всё это в код. Не в задачку «выучить наизусть структуру task_struct», а в реальные утилиты, которые делают то же самое, что делают системные инструменты — ps, shell, monitor — только сами и из ваших рук.

Capstone — это последний модуль курса. Здесь нет новой теории. Здесь только применение того, что уже знаете. Цель: после трёх уроков у вас в руках три рабочих инструмента и понимание, как они построены из примитивов ОС. Это знание невозможно получить чтением — только написанием.


Что мы построим

Три инструмента, каждый учит свой пласт ОС:

Три capstone-проекта

Каждый собирает свой кусок знаний из курса в работающий код

mini-psСвой ps на Python. Читает /proc/[pid]/stat, status, cmdline. Выводит PID, PPID, имя, состояние, RSS, vsize, threads. ~150 строк кода, покрывает модули процессов и /proc
mini-shellСвой shell. fork + execvp + pipe + I/O redirection + builtins (cd, pwd, exit). ~200 строк Python или 250 C. Покрывает модули процессов, IPC, file I/O
resource-monitorWatchdog: читает /proc/stat, /proc/meminfo, /proc/diskstats каждые N секунд. Считает разницу с прошлой выборкой, выводит CPU%, mem%, IO rate. Alerts при threshold. ~250 строк Python. Покрывает модули observability, file I/O

Каждый инструмент маленький — 150-250 строк. Но каждый — настоящий: вы запускаете его и видите, что он работает. И каждый раскрывает что-то, что нельзя получить из теории.


Зачем именно эти три

Можно было выбрать другое. Например, написать свой kernel module (но это требует kernel-headers и compile setup, не для всех платформ). Можно написать container runtime (но это deep dive в namespaces — отдельный мини-курс). Эти три выбраны потому, что каждый из них:

  1. Покрывает несколько модулей курса — нельзя написать mini-ps без понимания /proc, процессов, memory layout. Нельзя написать shell без fork/exec, signal handling, file descriptors.
  2. Запускается на любом Linux — нужен только Python 3 (или C компилятор для урока 3). Никаких прав root, никаких странных зависимостей.
  3. Имеет реальный аналогps, bash, top. Вы напишете свою упрощённую версию и узнаете, как устроены инструменты, которыми пользуетесь каждый день.
Что покрывает каждый инструмент

Mapping проектов на модули курса

mini-ps используетУрок 2: что такое процесс, PID, /proc. Урок 5: virtual memory, RSS vs VSZ. Урок 11: syscalls (open, read). Урок 14: /proc как kernel interface
02-processesProcess anatomy: что физически читать из /proc/[pid]
05-memory-managementRSS, VSZ, shared. Что эти числа значат на самом деле
11-syscallsopen + read для каждого файла в /proc
14-observability/proc как универсальный API к kernel state
mini-shell используетУрок 2: fork/exec. Урок 7: pipes, signals. Урок 9: file I/O, dup2 для redirection. Урок 10: setuid (если делаем sudo-mode)
02-processesfork() создаёт ребёнка, exec() заменяет образ. Wait для статуса
07-ipcpipe(): unidirectional FIFO между процессами. signal() для Ctrl+C
09-file-iodup2() для перенаправления stdin/stdout. open() для файлов в > <
monitor используетУрок 5: meminfo. Урок 14: /proc/stat для CPU, /proc/diskstats для I/O. Урок 7: signals для graceful shutdown
05-memory-managementMemTotal, MemAvailable, Buffers, Cached -- что значат
14-observabilityvmstat и iostat на самом деле читают эти же файлы. Узнаём как
07-ipcSIGTERM для graceful shutdown -- нужно ловить, успеть закрыть файлы

Стек технологий

Все три инструмента можно написать на Python 3. Это сознательный выбор:

  • Низкий barrier: не нужно настраивать gcc, libc-dev, валяться с segfault.
  • Высокая близость к syscalls: модули os и subprocess — тонкие обёртки над open(), fork(), exec(). Python-код читается почти как C.
  • Понятный output: f-strings и print с format давно лучше чем printf.

Для урока 3 (shell) опционально дам версию на C — потому что fork/exec в C это «как было задумано», и polezno хоть раз увидеть. Но если C не пишете — Python работает.

Никаких внешних зависимостей. Только stdlib. Это важно: вы должны увидеть, что весь этот функционал — из os, sys, signal, select. Никакого магического psutil (хотя в проде вы возьмёте именно его).


Архитектура каждого инструмента

Каждый из трёх инструментов следует одному паттерну:

Общий паттерн всех трёх инструментов

Read state from /proc -> parse -> compute -> output

ReadОткрыть файл в /proc, прочитать его содержимое. Это всё взаимодействие с kernel: для mini-ps читаем /proc/[pid]/*, для monitor /proc/stat. Shell не читает /proc, но fork/exec -- тоже syscalls
ParseСодержимое /proc -- текст с пробельными разделителями. /proc/[pid]/stat -- одна строка с 50+ полями. /proc/meminfo -- key: value. /proc/diskstats -- таблица колонок. Парсим в dict/dataclass
ComputeИз raw чисел делаем человеческое: KB -> MB, ticks -> CPU%, RSS / total_mem * 100. Здесь же diff с прошлой выборкой (для monitor)
OutputPrint в stdout с табуляцией и колонками. Для shell -- через subprocess.run заменено на fork+exec, output идёт в дескриптор который ребёнок наследует

Этот паттерн повторяется во всём системном софте. top читает /proc и форматирует. iostat читает /proc/diskstats и считает diff. vmstat читает /proc/stat + /proc/meminfo. Понимание этого паттерна снимает магию с системных тулз: они не делают ничего, что не можете вы.


Что вы получите

Дам конкретно по каждому инструменту, какие умения вы возьмёте после уроков 2-4 и labs:

Из mini-ps

  • Уверенное чтение /proc/[pid]/stat, /proc/[pid]/status, /proc/[pid]/cmdline — три файла с разной структурой.
  • Понимание разницы между RSS и VSZ — почему программа на 1 GB VSZ может занимать 50 MB RSS.
  • Базовая работа с состояниями процессов: R, S, D, Z, T — что значит каждое.
  • Парсинг таких хитрых форматов как (name) в stat, где name может содержать скобки и пробелы.
  • Итерация по /proc — собрать список всех PID.

Из mini-shell

  • fork() через os.fork(). Что значит «возвращает 0 у ребёнка, PID у родителя».
  • execvp() через os.execvp(). Что значит «заменяет образ текущего процесса».
  • wait() через os.waitpid(). Почему без него получаем зомби.
  • pipe() через os.pipe(). Как kernel связывает два процесса.
  • dup2() через os.dup2(). Как перенаправить stdin/stdout.
  • Сигналы: signal.signal() для Ctrl+C — почему просто try/except KeyboardInterrupt мало.
  • Простейший парсер shell-команд: tokens, операторы (|, >, <).

Из resource-monitor

  • Чтение /proc/stat для CPU времени по cores.
  • Чтение /proc/meminfo для total / available / cached / buffers.
  • Чтение /proc/diskstats для read/write секторов с time-since-boot.
  • Diff между выборками: CPU% = (delta_user + delta_system) / delta_total.
  • Threshold-based alerts и почему time.sleep() не точен.

Структура capstone-уроков

Каждый из уроков 2-4 имеет одну структуру:

  1. Что строим — описание утилиты с примером output.
  2. Архитектура — компоненты, поток данных, диаграмма.
  3. Implementation — ключевые куски кода с пояснениями.
  4. Edge cases — что ломается и как с этим справиться.
  5. Попробуй сам — расширения и эксперименты.
  6. KnowledgeCheck — закрепление.

В labs (отдельная директория labs/) есть полные templates с TODO, expected solutions, verify-скрипты. Уроки покажут логику и подходы, labs дадут структурированный hands-on с проверкой.


Чек-лист готовности

Перед началом убедитесь:

  • Доступ к Linux (нативно, WSL2 или Docker docker run -it python:3.13 bash).
  • Python 3.10+: python3 --version. Если ниже — поставьте 3.13 (большинство dist-репозиториев имеют).
  • Терминал, который не закроется через 5 минут idle (для shell-урока полезно).
  • ~3-4 часа на всё (45-60 минут на каждый урок + labs).

Если на macOS — Linux только в Docker/VM. macOS — это не Linux, у него другой формат /proc (его там нет вовсе, есть sysctl), другие syscalls (XNU kernel). Вы можете прочитать уроки на mac, но запустить код — только на Linux.

docker run: быстро поднять Linux-среду для capstone
# Если нет Linux под рукой
docker run --rm -it -v "$(pwd):/work" -w /work python:3.13 bash

# Внутри контейнера
ls /proc/1/
# должен показать: stat, status, cmdline, и ~40 других файлов

Попробуй сам

Прямо сейчас, до перехода к уроку 2:

  1. Откройте Linux-терминал (или Docker, как выше).
  2. Найдите PID своего shell: echo $$. Получите число, например 12345.
  3. Прочитайте, что про вас знает kernel:
cat /proc/$$/status | head -20

Вы увидите:

Name:	bash
Umask:	0022
State:	S (sleeping)
Tgid:	12345
Ngid:	0
Pid:	12345
PPid:	5432
TracerPid:	0
Uid:	1000	1000	1000	1000
Gid:	1000	1000	1000	1000
FDSize:	256
Groups:	4 24 27 30 46 100
VmPeak:	   12500 kB
VmSize:	   12400 kB
VmLck:	       0 kB
VmPin:	       0 kB
VmHWM:	    4800 kB
VmRSS:	    4800 kB

Это полностью то, что вытащит ps. И полностью то, что вы будете извлекать в уроке 2 для своего mini-ps. Уже виден формат: key:\twhitespace\tvalue. Парсится в пять строк.

Если получилось — вы готовы. Идём строить ps.

Проверка знанийKnowledge check
Все три capstone-инструмента опираются на один центральный механизм Linux -- какой?
ОтветAnswer

Итог

Capstone — это не «много новой теории», а «применение всей теории». Три инструмента (ps, shell, monitor) покрывают центральные модули курса: процессы, память, IPC, file I/O, /proc. Каждый — компактный (~150-250 строк), реальный, запускаемый на любом Linux.

В уроке 2 — mini-ps. Читаем /proc/[pid]/*, парсим, форматируем колонками. После него команда ps -ef | head потеряет любую загадочность.

Проверьте понимание

Результат: 0 из 0
Аналитический
Вопрос 1 из 6. В чём принципиальная разница между tutorial-проектом (Jaffle Shop, 5 моделей) и capstone production-grade pipeline (30+ моделей)? Какие 5 элементов production-ready пропущены в типичных туториалах?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4