Каждый, кто запускает ps, top, free или ss на Linux, уже пользуется /proc - просто не всегда это осознаёт. Все эти утилиты не имеют собственного доступа к памяти ядра, не делают специализированных системных вызовов для получения данных о процессах. Они просто открывают файлы в /proc и читают то, что ядро туда записало. По сути, весь пользовательский мониторинг в Linux стоит на фундаменте одной виртуальной файловой системы.

Впервые /proc появился в Linux в сентябре 1992 года в версии 0.97.3, а уже в декабре того же года начал расширяться за пределы чисто процессной информации. Концепция "процессы как файлы" была предложена Томом Килианом ещё в 1984 году на конференции USENIX, задолго до Linux. Но именно в Linux procfs вырос в нечто большее, чем просто удобный API для ps - в полноценную систему интроспекции ядра в реальном времени.

Почему proc не хранит никаких данных на диске

Файлы в /proc не существуют на диске. От слова совсем. Когда процесс открывает /proc/meminfo и читает её содержимое, ядро в этот момент формирует ответ прямо в оперативной памяти, собирая актуальные данные из своих внутренних структур. Файл создаётся в момент чтения и исчезает сразу после. Именно поэтому размер большинства файлов в /proc равен нулю байт по мнению ls -la - статическое поле размера просто не имеет смысла для динамически генерируемого содержимого.

Монтируется procfs при старте системы автоматически:

# Убедиться что procfs смонтирована
mount | grep proc

# Тип файловой системы
cat /proc/filesystems | grep proc

Под капотом procfs реализована через механизм VFS (Virtual File System) ядра Linux. Каждый "файл" - это зарегистрированный обработчик с функцией чтения, которая вызывается при обращении. Запись в некоторые файлы тоже работает - и это уже не чтение состояния, а изменение поведения ядра прямо в рантайме.

Анатомия директории процесса и что там реально хранится

Для каждого запущенного процесса, включая потоки ядра, в /proc существует директория с именем, совпадающим с PID. Набор файлов внутри стандартен для всех процессов, и изучение хотя бы одной такой директории даёт понимание всей структуры.

# Посмотреть содержимое директории процесса
ls -la /proc/$$

# Чем запущен процесс
cat /proc/$$/cmdline | tr '\0' ' '

# Переменные окружения процесса
cat /proc/$$/environ | tr '\0' '\n'

# Текущий рабочий каталог
readlink /proc/$$/cwd

# Исполняемый файл
readlink /proc/$$/exe

Файл status даёт сводную картину состояния процесса в читаемом формате: имя, PID, PPID, состояние (R/S/D/Z), потребление памяти, UID/GID, ограничения и флаги возможностей (capabilities):

cat /proc/$$/status

Файл maps показывает полную карту виртуальной памяти процесса - все сегменты, их права доступа, смещения и источники (анонимные страницы, файлы, разделяемые библиотеки):

cat /proc/1/maps | head -20

Директория fd/ содержит символические ссылки на все открытые файловые дескрипторы процесса. Это прямая замена lsof для конкретного процесса без дополнительных инструментов:

# Все открытые файлы процесса
ls -la /proc/$$/fd

# Только сокеты
ls -la /proc/$$/fd | grep socket

Системные файлы верхнего уровня для мониторинга ресурсов

За пределами PID-директорий /proc содержит десятки файлов с общесистемной информацией. Это первичные источники данных, которые читают htop, vmstat, sar и большинство других инструментов мониторинга.

Память и нагрузка - самые частые запросы при диагностике:

# Подробная статистика памяти
cat /proc/meminfo

# Средняя нагрузка за 1, 5 и 15 минут и число задач
cat /proc/loadavg

# Статистика по всем CPU: user, nice, system, idle, iowait, irq, softirq
cat /proc/stat

# Дисковая статистика: число операций, секторов, миллисекунды ожидания
cat /proc/diskstats

Информация о процессоре и системе:

# Подробная информация о каждом ядре CPU
cat /proc/cpuinfo

# Время работы системы в секундах
cat /proc/uptime

# Параметры загрузки ядра
cat /proc/cmdline

# Версия ядра
cat /proc/version

Сетевая подсистема представлена целой директорией /proc/net/, которая содержит таблицы состояния сетевого стека:

# TCP-соединения с состоянием и адресами в hex
cat /proc/net/tcp

# UDP-сокеты
cat /proc/net/udp

# Статистика сетевых интерфейсов (байты, пакеты, ошибки)
cat /proc/net/dev

# Таблица маршрутизации
cat /proc/net/route

# ARP-таблица
cat /proc/net/arp

Адреса в /proc/net/tcp хранятся в шестнадцатеричном формате с обратным порядком байт - особенность, которая поначалу удивляет. ss и netstat делают обратное преобразование автоматически, но при написании скриптов это нужно учитывать.

Управление параметрами ядра через /proc/sys

Директория /proc/sys - это не просто источник информации, а двунаправленный интерфейс управления. Запись в файлы внутри этой директории меняет поведение ядра немедленно, без перезагрузки и без перекомпиляции. Именно на этом механизме основана утилита sysctl.

# Прочитать параметр максимального числа открытых файлов
cat /proc/sys/fs/file-max

# Изменить параметр напрямую
echo 2097152 > /proc/sys/fs/file-max

# Включить форвардинг IP-пакетов
echo 1 > /proc/sys/net/ipv4/ip_forward

# Размер буфера TCP
cat /proc/sys/net/core/rmem_max

# Ограничения на overcommit памяти
cat /proc/sys/vm/overcommit_memory

Изменения через /proc/sys не сохраняются после перезагрузки. Для постоянного применения параметры записывают в /etc/sysctl.conf или файлы в /etc/sysctl.d/, а применяют через sysctl -p. Но для экстренной настройки работающего сервера прямая запись в /proc/sys работает мгновенно - и это принципиальное отличие от большинства других механизмов конфигурации ядра, где изменение вступает в силу только после перезагрузки.

Каждый параметр в /proc/sys соответствует конкретной переменной в исходном коде ядра. Это означает, что параметры документированы в официальной документации ядра в директории Documentation/admin-guide/sysctl/, и их поведение предсказуемо.

Опции монтирования procfs и безопасность в многопользовательских средах

Procfs спроектирован с допущением, что чтение информации о чужих процессах - нормально. На рабочем сервере это не всегда желательно: любой локальный пользователь может прочитать переменные окружения чужих процессов, увидеть список открытых файлов и узнать командные строки запущенных демонов.

Опция монтирования hidepid контролирует видимость чужих процессов:

# hidepid=0 - поведение по умолчанию, все процессы видны всем
# hidepid=1 - чужие /proc/PID существуют, но stat() возвращает только PID
# hidepid=2 - чужие /proc/PID полностью скрыты для непривилегированных

# Применить немедленно
mount -o remount,hidepid=2 /proc

# Постоянно через /etc/fstab
# proc /proc proc defaults,hidepid=2 0 0

Если нужно предоставить доступ к информации о процессах отдельным сервисам (например, мониторинговому агенту), используется параметр gid=:

# Создать группу мониторинга и разрешить ей видеть все процессы
groupadd monitoring
mount -o remount,hidepid=2,gid=$(getent group monitoring | cut -d: -f3) /proc

В контейнерных средах каждое pid-пространство имён получает собственный экземпляр procfs. Это означает, что внутри контейнера /proc показывает только процессы этого контейнера - изоляция работает на уровне ядра, а не фильтрацией вывода.

Практические сценарии диагностики через прямое чтение /proc

Бывают ситуации, когда стандартные утилиты недоступны - минимальный образ, broken environment, ограниченный chroot. В таких случаях /proc становится единственным инструментом.

Найти процесс, удерживающий удалённый файл (классическая задача когда диск "занят" после rm):

# Найти все удалённые файлы, которые ещё открыты
find /proc/*/fd -ls 2>/dev/null | grep deleted

# Узнать PID процесса держащего конкретный файл
grep -l "myfile" /proc/*/maps 2>/dev/null

Проверить лимиты файловых дескрипторов для процесса:

# Текущие и максимальные лимиты
cat /proc/$$/limits

# Сколько дескрипторов реально открыто
ls /proc/$$/fd | wc -l

Посмотреть планировщик и приоритет процесса:

# Scheduling policy и nice-значение
cat /proc/$$/sched 2>/dev/null | head -5
grep ^prio /proc/$$/stat

Procfs - это один из тех инструментов, ценность которого растёт обратно пропорционально тому, сколько других инструментов доступно. На полностью оснащённой системе с htop, perf, bpftrace и strace он остаётся в тени. Но в момент, когда нужно понять, что происходит прямо сейчас, без установки дополнительных пакетов, без специальных прав и без изменения системы - /proc там, где он всегда был: смонтирован, актуален и открыт для чтения.