С чего начать Первые шаги трек · 15 ступеней
Linux Labs

/proc: процессы и ядро в виде файлов

10 мин Ubuntu 24.04 · Linux 6.8

/proc — файловая система, в которой ядро показывает процессы (/proc/) и себя: память, load, параметры.

Шпаргалка

8 команд Версия для печати
  • ls /proc/1234/ всё о процессе 1234
  • grep -E 'State|PPid|VmRSS' /proc/1234/status
  • ls -l /proc/1234/fd открытые файлы и сокеты
  • cat /proc/1234/limits лимиты процесса
  • tr '\0' ' ' < /proc/1234/cmdline командная строка
  • sudo cat /proc/1234/environ | tr '\0' '\n' окружение
  • ls -l /proc/1234/cwd /proc/1234/exe каталог и программа
  • cat /proc/1234/cgroup служба или сеанс процесса

Обзор

/proc — файловая система, которой нет на диске. Ядро собирает содержимое её файлов в момент чтения. Каталог /proc/<PID> есть у каждого процесса, остальные файлы описывают систему целиком, а /proc/sys — параметры ядра. ps, top, free, uptime и pidstat берут данные отсюда.

text
student@ubuntu:~$ ls -l /proc/loadavg /proc/meminfo
-r--r--r-- 1 root root 0 Oct 21 00:17 /proc/loadavg
-r--r--r-- 1 root root 0 Oct 21 00:17 /proc/meminfo

Размер у файлов — 0: данных нет, пока их не прочитали. Читать их надо целиком — cat, grep, tr.

Каталог процесса

Файл Что внутри Кто читает
status имя, состояние, PPid, UID, память VmRSS, потоки Threads все
cmdline командная строка, аргументы через нулевой байт все
limits лимиты ресурсов: мягкий и жёсткий все
cgroup группа процесса: служба или сеанс все
oom_score, oom_score_adj оценка и поправка OOM все
task/ потоки процесса все
environ окружение на момент запуска владелец и root
fd/ открытые дескрипторы: файлы, сокеты, каналы владелец и root
cwd, exe текущий каталог и файл программы владелец и root
io байты чтения и записи владелец и root
maps области памяти и файлы в них владелец и root
stack стек ядра процесса root

Чужой процесс без sudo отвечает Permission denied, а wchan — нулём. /proc/self — каталог того процесса, который его читает: cat /proc/self/status покажет cat.

status

text
student@ubuntu:~$ sleep 300 &
[1] 971
student@ubuntu:~$ grep -E '^(Name|State|PPid|VmRSS)' /proc/971/status
Name:   sleep
State:  S (sleeping)
PPid:   956
VmRSS:      2028 kB
Поле Что значит
State состояние: R, S, D, Z, T (см. load-average)
PPid PID родителя
Uid четыре UID: реальный, действующий, сохранённый, для ФС
VmRSS память процесса в RAM (см. memory-swap)
Threads число потоков
voluntary_ctxt_switches сколько раз процесс сам отдал процессор

fd: открытые файлы

text
student@ubuntu:~$ ls -l /proc/$$/fd
total 0
lr-x------ 1 student student 64 Oct 21 00:17 0 -> /dev/null
…

Каждая ссылка — открытый дескриптор: номер и то, на что он указывает. Сокет выглядит как socket:[2076], канал — pipe:[…]. Число дескрипторов — ls /proc/<PID>/fd | wc -l; сравни его с Max open files в limits (см. ulimit).

Файл удалили, а процесс держит его открытым — ссылка кончается на (deleted), место на диске не освобождается (см. удалённый открытый файл):

text
student@ubuntu:~$ readlink /proc/956/fd/3
/tmp/app.log (deleted)

У службы systemd стандартный ввод — /dev/null, а вывод уходит в сокет журнала: у systemd-resolved 0 -> /dev/null, 1 -> socket:[3608].

exe и maps: программа и библиотеки

exe — ссылка на файл программы, maps — области памяти процесса и файлы, отображённые в них: сама программа и каждая общая библиотека. libc.so.6 на учебной машине отображена в 38 процессов сразу.

Обновление заменяет файл на диске новым, а процесс продолжает выполнять старый. Ссылка exe и строки maps тогда кончаются на (deleted):

text
student@ubuntu:~$ sudo readlink /proc/4214/exe
/usr/local/bin/demo-sleep (deleted)
student@ubuntu:~$ sudo grep deleted /proc/3830/maps | head -2
7ac7bbf1f000-7ac7bbf21000 r--p 00000000 fd:04 2727
  /usr/local/lib/libdemo.so.1 (deleted)
7ac7bbf21000-7ac7bbf33000 r-xp 00002000 fd:04 2727
  /usr/local/lib/libdemo.so.1 (deleted)

Столбцы maps: адреса области, права (r-xp — код), смещение в файле, устройство, inode и путь. Исправление в новой версии на такой процесс не действует, пока его не перезапустят. Найти все такие процессы:

bash
sudo grep -l deleted /proc/[0-9]*/maps 2>/dev/null

Смотри путь: строки /memfd:… (deleted) — память без файла на диске, к обновлению они не относятся. То же для служб с готовой командой перезапуска печатает needrestart (см. unattended-upgrades), в lsof такие файлы отмечены DEL (см. lsof).

Блокировки: /proc/locks

text
student@ubuntu:~$ cat /proc/locks | head -2
1: FLOCK  ADVISORY  WRITE 1094 fd:04:2703 0 EOF
1: -> FLOCK  ADVISORY  WRITE 1112 fd:04:2703 0 EOF

Каждая строка — блокировка файла: тип (FLOCK от flock, POSIX от fcntl), WRITE или READ, PID владельца, устройство и inode файла (fd:04:2703 — inode 2703, как в столбце NODE у lsof). Строка с -> — процесс 1112 ждёт эту блокировку. Держит её процесс 1094.

cmdline и environ

Аргументы в cmdline и переменные в environ разделены нулевым байтом, tr превращает их в пробелы или строки:

text
student@ubuntu:~$ tr '\0' ' ' < /proc/971/cmdline
sleep 300
student@ubuntu:~$ sudo cat /proc/1/environ | tr '\0' '\n' | head -2
HOME=/
init=/sbin/init

environ — окружение на момент запуска: export в работающей оболочке в него не попадёт, его увидят только процессы, запущенные после. У потоков ядра (kthreadd и других) cmdline пустой.

limits и cgroup

/proc/<PID>/limits — лимиты, с которыми процесс работает сейчас. Их меняют ulimit, LimitNOFILE= службы и prlimit; поправка в юните без перезапуска службы сюда не попадает (см. ulimit).

text
student@ubuntu:~$ cat /proc/1211/cgroup
0::/system.slice/ssh.service
student@ubuntu:~$ cat /proc/$$/cgroup
0::/user.slice/user-1000.slice/session-c1.scope

cgroup отвечает, чей процесс: службы ssh.service или сеанса пользователя. То же короче — ps -o pid,unit,comm -p <PID>.

Файлы о системе

Файл Что внутри
/proc/loadavg load average и число задач (см. load-average)
/proc/meminfo память: MemTotal, MemAvailable, Cached (см. memory-swap)
/proc/pressure/ доля времени ожидания CPU, памяти, диска
/proc/cpuinfo процессоры и их модель
/proc/uptime секунды с загрузки и суммарный простой процессоров
/proc/cmdline параметры, с которыми загружено ядро
/proc/mounts смонтированные файловые системы
/proc/swaps активный swap
/proc/sys/ параметры ядра (см. sysctl)

/proc/sys

Каждый параметр ядра — файл: vm.swappiness — это /proc/sys/vm/swappiness, точки в имени заменяют косую черту. sysctl читает и пишет эти же файлы. Запись — через tee:

bash
cat /proc/sys/vm/swappiness
echo 10 | sudo tee /proc/sys/vm/swappiness

Рецепты

3

Что это за процесс

bash
grep -E 'Name|State|PPid|Uid' /proc/1211/status
tr '\0' ' ' < /proc/1211/cmdline; echo
sudo ls -l /proc/1211/cwd /proc/1211/exe
cat /proc/1211/cgroup

Имя, родитель, пользователь, полная команда, рабочий каталог, файл программы и служба — этого хватает, чтобы понять, откуда процесс взялся.

Найти и вернуть удалённый, но открытый файл

bash
sudo find /proc/[0-9]*/fd -lname '*(deleted)' 2>/dev/null
cp /proc/956/fd/3 /tmp/restored.log   # копия содержимого

find печатает ссылки вида /proc/956/fd/3: PID и номер дескриптора. Пока процесс жив, файл можно скопировать по этой ссылке. Место освободится, когда процесс закроет файл или завершится.

Окружение службы

bash
pid=$(systemctl show -p MainPID --value ssh)
sudo cat /proc/$pid/environ | tr '\0' '\n'

Неполадки

4

Permission denied у чужого процесса

text
student@ubuntu:~$ ls /proc/276/fd
ls: cannot open directory '/proc/276/fd': Permission denied

fd, environ, cwd, exe, io, maps чужого процесса читает только root. Повтори с sudo.

sudo есть, а Permission denied всё равно

text
student@ubuntu:~$ sudo tr '\0' '\n' < /proc/1/environ
-bash: /proc/1/environ: Permission denied
student@ubuntu:~$ sudo echo 1 > /proc/sys/vm/drop_caches
-bash: /proc/sys/vm/drop_caches: Permission denied

Перенаправления < и > выполняет твоя оболочка без прав root, sudo действует только на команду. Читай sudo cat … | tr …, пиши echo … | sudo tee ….

No such file or directory

Процесс уже завершился, и его каталог исчез вместе с ним. PID мог занять новый процесс — сверь cmdline.

В environ нет переменной, которую задали

Переменную задали после запуска процесса. environ её не покажет — перезапусти процесс с нужным окружением.

Термины

1
общая библиотека (shared library)
Файл .so с кодом, который подключают многие программы сразу (libc.so.6, libssl.so.3): ядро отображает его в память каждого процесса-пользователя. Новая версия библиотеки действует на процесс только после его перезапуска. Ещё встречается в: lsof, unattended-upgrades: обновления безопасности без участия человека, Символические и жёсткие ссылки, Память и swap: free, available и кэш страниц

См. также

  • processes — PID, состояния и сигналы.
  • ps — список процессов из /proc.
  • lsof — открытые файлы всех процессов.
  • strace — системные вызовы процесса.
  • ulimit — лимиты из /proc/<PID>/limits.
  • sysctl — параметры ядра в /proc/sys.
  • load-average — /proc/loadavg и состояние D.
  • memory-swap — /proc/meminfo и RSS.
Загрузка…