Файловый дескриптор (file descriptor, FD) — это целое число, которое процесс в Linux использует для доступа к открытому файлу, сокету, каналу или устройству.
Фактически это указатель на открытую запись в таблице открытых файлов ядра.

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

Как это устроено

  1. Когда процесс открывает файл (через open()), ядро создаёт запись в таблице открытых файлов, где хранится:
    • номер inode;
    • текущая позиция чтения/записи;
    • флаги (например, O_RDONLY, O_APPEND);
    • счётчик ссылок на это открытие.
  2. Процесс получает номер дескриптора (обычно от 0 и выше).
  3. Все операции read(), write(), lseek(), close() работают не с именем файла, а с этим номером.

Стандартные дескрипторы

Каждый процесс при запуске получает три стандартных дескриптора:

НомерИмяНазначениеСтандартное устройство
0stdinстандартный вводклавиатура
1stdoutстандартный выводтерминал
2stderrстандартный вывод ошибоктерминал

Пример перенаправления:

command > out.txt       # перенаправить stdout в файл
command 2> err.txt      # перенаправить stderr
command > all.txt 2>&1  # объединить stdout и stderr

Просмотр открытых дескрипторов

Посмотреть, какие файлы открыты процессом:

ls -l /proc/<PID>/fd

Например:

ls -l /proc/1234/fd

Выведет ссылки вида:

0 -> /dev/pts/0
1 -> /home/user/output.log
2 -> /dev/null
3 -> /tmp/socket

Фактически /proc/<PID>/fd/ — это интерфейс в /proc, через который можно увидеть, какие файлы реально открыты процессом.

Поиск процессов, держащих файл открытым

Если нужно узнать, какой процесс использует файл:

lsof /path/to/file

или:

fuser /path/to/file

Управление лимитами на дескрипторы

Каждый процесс ограничен по количеству одновременно открытых файлов. Проверить текущий лимит:

ulimit -n

Изменить временно (для текущей сессии):

ulimit -n 4096

Изменить постоянно можно в файле /etc/security/limits.conf или через systemd (LimitNOFILE=).

Закрытие дескрипторов

После работы с файлом процесс обязан закрывать его:

close(fd);

Если файл не закрыт — он остаётся в системе до завершения процесса.
Если файл был удалён (rm file), но процесс его держит открытым, данные занимают место до закрытия дескриптора.

Проверить такие случаи:

lsof | grep deleted

📊 Ключевые моменты

  • Дескриптор — это локальный идентификатор открытого файла в рамках конкретного процесса.
  • Несколько процессов могут иметь дескрипторы, указывающие на один и тот же inode.
  • После fork() дочерний процесс наследует дескрипторы родителя.
  • После exec() процесс обычно сохраняет только стандартные дескрипторы, если явно не указано иное.

Сводка команд

ЦельКомандаПримечание
Показать открытые дескрипторы процессаls -l /proc/<PID>/fdПоказывает все открытые файлы
Найти процесс, держащий файлlsof fileИли fuser file
Проверить лимит дескрипторовulimit -nПо умолчанию ~1024
Изменить лимит временноulimit -n <число>Только для текущей сессии
Проверить “зависшие” удалённые файлы`lsofgrep deleted`