procfs и sysfs
/proc и /sys — виртуальные файловые системы, генерируемые ядром по запросу в RAM: никаких байтов на диске. Открывают живые таблицы процессов, счётчики памяти, CPU-флаги и параметры оборудования как обычные файлы; записи /sys можно изменять для настройки ядра на ходу.
Ты хочешь узнать, сколько памяти свободно прямо сейчас. Запускаешь free -h. Это число откуда-то берётся — и это не запрос к базе данных и не демон, опрашивающий железо. Ядро открывает живой учёт памяти как текстовый файл в /proc/meminfo. В момент, когда ты выполняешь cat, ядро собирает содержимое из внутренних структур данных и передаёт тебе. Когда ты закрываешь файл, содержимое исчезает. Ничего на диске нет.
Такова конструкция: ядро экспортирует своё собственное состояние как файловую систему. /proc и /sys — два основных окна. Понимание того, что там живёт, — разница между угадыванием состояния системы и прямым чтением из источника.
После этого урока ты сможешь использовать /proc/meminfo, /proc/cpuinfo и записи /proc/<PID>/ для проверки живого состояния системы, использовать /sys для чтения информации об оборудовании и драйверах, а также объяснить, почему эти файлы генерируются по запросу, а не сохраняются на диск.
procfs (/proc) — виртуальная файловая система, монтируемая при загрузке. Ядро регистрирует специальный тип файловой системы proc. При загрузке системы systemd монтирует его в /proc. Дисковое пространство не выделяется — нет блоков, нет inode в традиционном смысле. Каждый раз, когда ты открываешь файл в /proc, VFS (Virtual Filesystem Switch) вызывает функцию ядра, которая строит ответ в памяти и возвращает его. Когда ты закрываешь файловый дескриптор, память освобождается.
mount | grep proc
# proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
ls /proc
# ты видишь пронумерованные директории (PID) плюс глобальные файлы: meminfo, cpuinfoПронумерованные директории — это процессы. /proc/1/ — PID 1 (systemd). /proc/$$ — твоя текущая оболочка (bash подставляет $$ на свой PID).
Глобальные файлы /proc открывают общесистемное состояние ядра. Это файлы, которые ты читаешь чаще всего при диагностике:
cat /proc/meminfo # все счётчики памяти в кБ: MemTotal, MemFree, Cached, Buffers…
cat /proc/cpuinfo # по ядру: модель, МГц, размер кэша, флаги CPU
cat /proc/loadavg # средние значения нагрузки за 1/5/15 мин + число задач
cat /proc/uptime # секунды с момента загрузки (два числа: общее, время простоя)
cat /proc/version # строка версии ядра
cat /proc/mounts # текущие смонтированные файловые системы
cat /proc/net/tcp # таблица TCP-сокетов в hex (ss и netstat читают это)Инструменты top, htop, free, uptime и netstat получают данные, читая эти файлы и переформатируя вывод. Понимание источника делает тебя независимым от этих инструментов — в минимальном контейнере без установленного top ты всё равно можешь диагностировать давление памяти, читая /proc/meminfo напрямую.
Директории по PID дают живой вид любого процесса. Для любого PID ты можешь прочитать:
PID=1
ls /proc/$PID/
cat /proc/$PID/status # состояние (running/sleeping), Uid, Gid, использование памяти (VmRSS, VmSize)
cat /proc/$PID/cmdline # полная командная строка (разделена нулями, используй tr '\0' ' ')
cat /proc/$PID/environ # переменные окружения (разделены нулями)
ls -la /proc/$PID/fd/ # открытые файловые дескрипторы (каждый — симлинк на реальный файл/сокет)
cat /proc/$PID/maps # карта виртуальной памяти: каждый сегмент с правами и backing file
cat /proc/$PID/net/tcp # сетевые соединения для сетевого namespace этого PIDПоддиректория fd/ особенно полезна: она показывает точно, какие файлы открыл процесс. Если процесс держит открытым удалённый файл (частая причина «диск заполнен, но больших файлов нет»), ты можешь увидеть это здесь:
ls -la /proc/$PID/fd/ | grep deletedsysfs (/sys) открывает объекты ядра и параметры оборудования. Если /proc изначально предназначался для информации о процессах (и накопил много глобальных данных со временем), /sys был спроектирован с самого начала как структурированное представление внутренней иерархии объектов ядра — устройства, шины, драйверы, управление питанием.
ls /sys/block/ # блочные устройства (диски)
cat /sys/block/sda/size # размер диска в секторах по 512 байт
cat /sys/class/net/ # сетевые интерфейсы
cat /sys/class/net/eth0/speed # скорость соединения в Мбит/с
cat /sys/class/net/eth0/carrier # 1 = соединение активно, 0 = неактивно
cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq # текущая частота CPU в кГцВ отличие от /proc, который в основном является глобальными данными только для чтения, многие записи в /sys доступны для записи — запись в них немедленно меняет поведение ядра:
# Пример: отключить масштабирование частоты CPU (для нагрузок, чувствительных к задержке)
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governorЭти изменения не сохраняются между перезагрузками. Постоянные изменения параметров ядра выполняются через sysctl (рассматривается в юните 12).
Производительность: чтение /proc почти бесплатно. cat /proc/meminfo не требует дискового I/O, никакого обращения к демону, никакого сетевого вызова. Ядро собирает ответ за микросекунды. Именно поэтому shell-скрипты для мониторинга часто используют прямое чтение из /proc — это быстрее и надёжнее, чем разбор вывода инструментов.
Оговорка: некоторые операции чтения /proc ненадолго захватывают блокировки ядра. На системе под экстремальной нагрузкой cat /proc/PID/maps для процесса с тысячами отображений памяти может блокироваться на миллисекунды. А чтение /proc/net/tcp на сервере с сотнями тысяч соединений включает полный сканирование таблицы на стороне ядра. Знай, что ты читаешь, прежде чем скриптовать это в плотный цикл.
Найди, какой процесс держит порт открытым, без netstat и lsof.
# /proc/net/tcp перечисляет все TCP-соединения в hex
# Колонка 2 — локальный адрес (hex IP:порт), колонка 4 — состояние (0A = LISTEN)
grep ' 0A ' /proc/net/tcp
# Колонка inode (10-я) связывает с процессом
# Найди, какой процесс владеет этим inode:
inode=12345 # замени на номер inode из grep выше
ls -la /proc/*/fd 2>/dev/null | grep "socket:\[$inode\]"
# PID — в пути: /proc/<PID>/fd/<n> -> socket:[12345]Именно это делают ss -tlnp и lsof -i :PORT внутри — они разбирают /proc/net/tcp и сопоставляют inode с файловыми дескрипторами процессов через /proc/<PID>/fd/. Инструменты — удобства; данные живут в /proc.
▸Почему это работает
В macOS нет /proc и /sys. Эквивалент — sysctl -a (читает из MIB sysctl ядра) и dtrace/fs_usage для интроспекции на уровне процессов. Принцип «всё есть файл» — философия Linux/Unix, но macOS выбрал другие механизмы. Когда Docker запускает контейнер Linux на твоём Mac, контейнер видит настоящий /proc — его предоставляет ядро Linux внутри HyperKit, а не macOS.
▸Частая ошибка
Классическая ловушка: ты удаляешь большой лог-файл, чтобы освободить место на диске, но df всё равно показывает файловую систему заполненной. Причина в том, что запущенный процесс (например, nginx) всё ещё держит файл открытым через файловый дескриптор. В Linux блоки диска файла не освобождаются, пока не закрыты все файловые дескрипторы, указывающие на него, даже если запись директории (имя) удалена. Найди виновника с помощью ls -la /proc/*/fd 2>/dev/null | grep deleted — затем либо перезапусти процесс, либо отправь ему SIGHUP для повторного открытия лог-файлов.
Ты запускаешь: cat /proc/meminfo. В какой момент вывод записывается в файл /proc/meminfo на диске?
procfs (/proc) и sysfs (/sys) — виртуальные файловые системы, которые ядро генерирует полностью в RAM — ничего на диске нет. Чтение /proc/meminfo, /proc/cpuinfo или /proc/<PID>/status вызывает обработчик ядра, собирающий вывод из живых внутренних структур данных. /proc/<PID>/fd/ показывает каждый открытый файловый дескриптор процесса; /proc/net/tcp содержит сырую таблицу TCP-соединений. /sys открывает иерархию аппаратных объектов ядра и предоставляет записываемые параметры, которые можно менять во время работы. Инструменты вроде free, ps, ss и netstat читают из этих виртуальных файлов и переформатируют вывод — ты всегда можешь обратиться к источнику напрямую.
Практика
Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.
Что-то непонятно?
Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.