Файловый дескриптор (file descriptor, FD) — это целое число, которое процесс в Linux использует для доступа к открытому файлу, сокету, каналу или устройству.
Фактически это указатель на открытую запись в таблице открытых файлов ядра.
Каждый процесс имеет свою таблицу дескрипторов, через которую он взаимодействует с ядром при чтении, записи или других операциях с файлами.
Как это устроено
- Когда процесс открывает файл (через
open()), ядро создаёт запись в таблице открытых файлов, где хранится:- номер inode;
- текущая позиция чтения/записи;
- флаги (например,
O_RDONLY,O_APPEND); - счётчик ссылок на это открытие.
- Процесс получает номер дескриптора (обычно от 0 и выше).
- Все операции
read(),write(),lseek(),close()работают не с именем файла, а с этим номером.
Стандартные дескрипторы
Каждый процесс при запуске получает три стандартных дескриптора:
| Номер | Имя | Назначение | Стандартное устройство |
|---|---|---|---|
| 0 | stdin | стандартный ввод | клавиатура |
| 1 | stdout | стандартный вывод | терминал |
| 2 | stderr | стандартный вывод ошибок | терминал |
Пример перенаправления:
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 <число> | Только для текущей сессии |
| Проверить “зависшие” удалённые файлы | `lsof | grep deleted` |