/proc
Виртуальная ФС с данными ядра — аргументы, окружение и открытые файлы процесса, память, нагрузка
/proc — не настоящие файлы на диске, а окно в ядро. Каждый процесс виден как каталог /proc/<PID>/, а файлы вроде /proc/meminfo описывают систему целиком. Содержимое генерируется в момент чтения, поэтому размер у большинства файлов — 0, а читать их нужно cat, grep, tr, а не по размеру. Именно отсюда берут данные ps, top, free, pgrep.
Синтаксис
cat /proc/<PID>/файл
ls -l /proc/<PID>/fd
cat /proc/файл
/proc/self — ссылка на каталог процесса, который её читает: ls -l /proc/self/fd покажет дескрипторы самого ls. $$ в bash — PID текущей оболочки.
Каталог процесса /proc/<PID>/
| Файл | Что внутри |
|---|---|
cmdline | командная строка; аргументы разделены нулевым байтом, не пробелом |
comm | имя процесса (до 15 символов) — то, что ищет pgrep без -f |
environ | переменные окружения на момент запуска, разделены \0; читать может только владелец или root |
status | человекочитаемая сводка: Name, State, PPid, Uid, Gid, VmRSS, Threads, SigIgn… |
fd/ | открытые дескрипторы: симлинки 0, 1, 2, 3… на файлы, сокеты (socket:[inode]), каналы (pipe:[…]) |
fdinfo/N | позиция и флаги открытого дескриптора N |
cwd | симлинк на текущий каталог процесса |
exe | симлинк на исполняемый файл (даже удалённый — с пометкой (deleted)) |
root | симлинк на корень процесса (отличается при chroot) |
maps | карта памяти: какие библиотеки и файлы отображены |
limits | лимиты: открытые файлы, процессы, размер core и т.д. |
io | сколько байт процесс прочитал и записал |
stat | то же, что status, одной строкой для программ (поля по номерам) |
task/ | потоки процесса — по каталогу на поток |
oom_score | насколько процесс «привлекателен» для OOM killer (больше — раньше убьют) |
cgroup | в какой cgroup процесс |
Поля /proc/<PID>/status
| Поле | Значение |
|---|---|
Name | имя процесса |
State | R, S, D, Z, T — как в ps |
PPid | PID родителя |
Uid / Gid | реальный, эффективный, сохранённый, файловый ID |
VmRSS | занятая физическая память; VmSize — виртуальная; VmPeak — пик |
Threads | число потоков |
SigIgn / SigCgt | битовые маски игнорируемых / перехватываемых сигналов (бит N−1 — сигнал N) |
voluntary_ctxt_switches | сколько раз процесс сам уступил CPU (ждал ввода-вывода) |
Системные файлы
| Файл | Что внутри |
|---|---|
/proc/loadavg | средняя нагрузка за 1, 5, 15 минут; работающие/всего потоков; последний PID |
/proc/meminfo | память: MemTotal, MemAvailable (сколько реально доступно), Cached, SwapFree |
/proc/cpuinfo | процессоры; число ядер — grep -c ^processor или nproc |
/proc/uptime | секунды с загрузки и суммарное время простоя всех CPU |
/proc/mounts | смонтированные ФС (как mount без аргументов) |
/proc/swaps | подключённый своп |
/proc/version | версия ядра |
/proc/net/tcp, /proc/net/udp | сокеты в шестнадцатеричном виде (удобнее ss) |
/proc/sys/… | параметры ядра; то же, что sysctl (/proc/sys/fs/file-max = fs.file-max) |
Примеры
# командная строка процесса с пробелами вместо \0
tr '\0' ' ' < /proc/1234/cmdline; echo
# каждый аргумент отдельной строкой
xargs -0 -n1 < /proc/1234/cmdline
# окружение процесса, по переменной на строку
tr '\0' '\n' < /proc/1234/environ
# родитель, состояние и память
grep -E '^(Name|State|PPid|VmRSS)' /proc/1234/status
# какие файлы открыл процесс и сколько их
ls -l /proc/1234/fd
ls /proc/1234/fd | wc -l
# где процесс «стоит» и что за бинарник
readlink /proc/1234/cwd /proc/1234/exe
# свободная память и нагрузка
grep MemAvailable /proc/meminfo
cat /proc/loadavg
Удалённый, но открытый файл
Если удалить файл, который держит открытым процесс, имя исчезнет, но данные останутся на диске, пока процесс не закроет дескриптор. Классический симптом: df показывает, что диск заполнен, а du столько файлов не находит. lsof в песочнице нет, но /proc даёт то же самое:
# все дескрипторы, указывающие на удалённые файлы — PID виден в пути
ls -l /proc/*/fd/* 2>/dev/null | grep '(deleted)'
# l-wx------ 1 root root 64 … /proc/7/fd/3 -> /tmp/data.txt (deleted)
# то же через find, компактнее
find /proc/[0-9]*/fd -lname '*(deleted)' -printf '%p -> %l\n' 2>/dev/null
# достать содержимое удалённого файла, пока процесс жив
cp /proc/7/fd/3 /tmp/recovered
# освободить место без остановки процесса — обнулить файл через дескриптор
: > /proc/7/fd/3
Место окончательно освободится, когда процесс закроет файл — после перезапуска или по сигналу, если программа умеет переоткрывать логи.
Подводные камни
cat /proc/PID/cmdlineсклеивает аргументы: разделители —\0, терминал их не показывает. Используйtr '\0' ' 'илиxargs -0.environ— окружение на момент запуска. Переменные, которые процесс поменял у себя позже, там не отразятся.- Пиши
ls -l /proc/*/fd/*, а не/proc/*/fd. Во втором случае PID будет в отдельных заголовках каталогов, иgrepего отрежет. - Процесс может исчезнуть посреди чтения. Ошибки вида
No such file or directoryпри обходе/proc/*— норма; глуши их2>/dev/null. - Чужие
fd,environ,cwdвидит только владелец или root. /proc/sysв контейнере обычно только для чтения:echo 1 > /proc/sys/…вернётRead-only file system. Параметры ядра для контейнера задаются снаружи.- В контейнере
/proc/meminfoи/proc/cpuinfoчасто показывают ресурсы всего хоста, а не лимиты контейнера.