← Назад к вопросам

Как понять какие файлы открыты приложением в Linux

1.8 Middle🔥 161 комментариев
#Linux и администрирование

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Определение открытых файлов процессом в Linux

В Linux «открытый файл» — это более широкое понятие, чем просто файл на диске. Это может быть регулярный файл, директория, сокет, символическая ссылка, блочное или символьное устройство, именованный канал (FIFO). Каждому открытому файлу в ядре соответствует файловый дескриптор (file descriptor) в пространстве процесса. Для понимания, какие файлы открыты приложением, существует несколько ключевых инструментов и мест в виртуальной файловой системе /proc.

Ключевые подходы и инструменты

1. Использование /proc — основного источника информации

Каждый процесс имеет поддиректорию /proc/<PID>/, где содержится детальная информация. Для анализа открытых файлов наиболее важны:

  • /proc/<PID>/fd/ — виртуальная директория, содержащая символические ссылки на все открытые файловые дескрипторы процесса. Имена ссылок — это номера дескрипторов (0, 1, 2, ...).
  • /proc/<PID>/fdinfo/ — содержит информацию о каждом дескрипторе (например, режим доступа, позицию в файле).
  • /proc/<PID>/maps — показывает память процесса, в том числе файлы, отображенные в память (например, разделяемые библиотеки).
# Найти PID процесса (например, nginx)
pgrep nginx

# Посмотреть все открытые файловые дескрипторы процесса 1234
ls -la /proc/1234/fd/

# Более информативный вывод с разрешением путей
ls -l /proc/1234/fd/ | awk '{print $9, $10, $11}'

2. Утилита lsof (List Open Files)

Это самый мощный и удобный инструмент. Она агрегирует информацию из /proc в человеко-читаемом виде.

# Показать все файлы, открытые процессом с PID 1234
lsof -p 1234

# Показать все файлы, открытые процессом по имени
lsof -c nginx

# Показать открытые файлы в конкретной директории
lsof +D /var/log

# Показать, какой процесс открывает конкретный файл
lsof /var/log/syslog

# Показать все сетевые соединения (файлы типа IPv4/IPv6)
lsof -i

3. Утилита fuser (File User)

Показывает, какие процессы используют указанные файлы или сокеты. Особенно полезна для выяснения, что мешает размонтировать файловую систему.

# Показать PID процессов, использующих файл
fuser -v /var/log/syslog

# Показать PID процессов, использующих TCP-порт 80
fuser -v 80/tcp

# Принудительно завершить процессы, использующие файл
fuser -k /mnt/usbdrive/file.txt

Пример анализа: что означают выводы

Допустим, мы смотрим lsof -p <PID> для веб-сервера. В выводе мы можем увидеть:

  • Дескрипторы 0, 1, 2 (stdin, stdout, stderr): Это могут быть файлы, терминалы (/dev/pts/0) или, чаще, сокеты или именованные каналы, если процесс работает как демон и его логи пишутся в journald (/dev/null для неиспользуемых).
  • Регулярные файлы (REG): Конфигурационные файлы (/etc/nginx/nginx.conf), файлы логов (/var/log/nginx/access.log), статические ресурсы сайта.
  • Директории (DIR): Рабочая директория процесса, корневые директории для чтения файлов.
  • Сетевые сокеты (IPv4/IPv6): Слушающие сокеты (*:80, *:443) и установленные соединения с клиентами.
  • Разделяемые библиотеки (не в fd, но в maps): Файлы с типом mem в lsof или списки в /proc/<PID>/maps (например, libc.so.6).

Практическое применение для DevOps

  • Диагностика «Device or resource busy»: Перед размонтированием тома или удалением файла с помощью fuser или lsof можно найти блокирующий процесс.
  • Расследование утечек ресурсов: Поиск процессов с аномально большим количеством открытых дескрипторов (ls /proc/<PID>/fd | wc -l) может указать на file descriptor leak в приложении.
  • Аудит безопасности: Выявление неожиданных открытых сетевых портов или чтения конфиденциальных файлов.
  • Оптимизация производительности: Анализ maps и открытых библиотек помогает понять, какие компоненты загружены в память.

Работа с дескрипторами на низком уровне

Иногда требуется глубокая диагностика. Можно читать информацию напрямую из /proc.

# Посмотреть, куда ссылается дескриптор 5 процесса 1234
readlink /proc/1234/fd/5

# Посчитать количество открытых дескрипторов в процессе
count=$(ls /proc/1234/fd/ | wc -l)
echo "Process 1234 has $count file descriptors open."

# Посмотреть memory mapped файлы (очень полезно для анализа использования библиотек)
cat /proc/1234/maps

Важное замечание: В современных дистрибутивах, использующих systemd, стандартные потоки вывода/ошибок демонов часто перенаправляются в socket для journald. Поэтому в lsof для stdout демона вы можете увидеть не обычный файл, а что-то вроде socket:[12345678].

Таким образом, комплексное использование /proc, lsof и fuser дает полную картину всех «файлов» (в широком смысле), с которыми взаимодействует приложение, что является фундаментальным навыком для отладки, мониторинга и обеспечения безопасности в Linux-средах.