Когда программа просит открыть файл - или другой ресурс данных, например, сетевой сокет - ядро операционной системы предоставляет доступ, делает запись в глобальной таблице файлов и предоставляет программному обеспечению местоположение этой записи.
Дескриптор идентифицируется уникальным неотрицательным целым числом, таким как 0, 12 или 567 . По крайней мере один файловый дескриптор существует для каждого открытого файла в системе.
Файловые дескрипторы были впервые использованы в Unix и используются современными операционными системами, включая Linux, macOS X и BSD. В Microsoft Windows файловые дескрипторы известны как файловые дескрипторы.
- обзор
- Стандартный, стандартный и стандартный
- Перенаправление файловых дескрипторов
Когда процесс делает успешный запрос на открытие файла, ядро возвращает дескриптор файла, который указывает на запись в глобальной файловой таблице ядра. Запись в таблице файлов содержит такую информацию, как индекс файла, смещение в байтах и ограничения доступа для этого потока данных (только для чтения, только для записи и т. Д.).
Стандартный, стандартный и стандартный
В Unix-подобной операционной системе первыми тремя файловыми дескрипторами по умолчанию являются STDIN (стандартный ввод), STDOUT (стандартный вывод) и STDERR (стандартная ошибка).
название | Файловый дескриптор | Описание | Сокращение |
---|---|---|---|
Стандартный ввод | 0 | Поток данных по умолчанию для ввода, например, в конвейере команд. В терминале по умолчанию используется ввод с клавиатуры пользователем. | STDIN |
Стандартный вывод | 1 | Поток данных по умолчанию для вывода, например, когда команда печатает текст. В терминале это по умолчанию экран пользователя. | стандартный вывод |
Стандартная ошибка | 2 | Поток данных по умолчанию для вывода, который относится к возникновению ошибки. В терминале это по умолчанию экран пользователя. | STDERR |
Перенаправление файловых дескрипторов
Доступ к дескрипторам файлов может осуществляться напрямую с использованием bash, оболочки по умолчанию для Linux, macOS X и подсистемы Windows для Linux.
Например, когда вы используете команду find, успешный вывод идет в stdout (дескриптор файла 1 ), а сообщения об ошибках - в stderr (дескриптор файла 2 ). Оба потока отображаются как вывод терминала:
найти / -name '* что-то *'
/ usr / share / doc / что-то / usr / share / doc / что-то / examples / something_random find: `/ run / udisks2 ': поиск запрещен:` / run / wpa_supplicant': отказано в разрешении / usr / share / нечто / usr / игры / что-то
Мы получаем ошибки, потому что find пытается найти несколько системных каталогов, которые мы не имеем права на чтение. Все строки с надписью «Отказано в доступе » были записаны в stderr, а остальные строки были записаны в stdout .
Вы можете скрыть stderr, перенаправив файловый дескриптор 2 в / dev / null, специальное устройство в Linux, которое «никуда не денется»:
найти / -name '* что-то *' 2> / dev / null
/ usr / поделиться / doc / что-то / usr / поделиться / doc / что-то / примеры / что-то случайное / usr / поделиться / что-то / usr / игры / что-то
Ошибки были отправлены в / dev / null и не отображаются.
Понимание разницы между stdout и stderr важно, когда вы хотите работать с выводом программы. Например, если вы попытаетесь выполнить grep в выводе команды find, вы заметите, что сообщения об ошибках не фильтруются, потому что в grep передается только стандартный вывод.
найти / -name '* что-то *' | grep 'что-то'
/ usr / share / doc / что-то / usr / share / doc / что-то / examples / something_random find: `/ run / udisks2 ': поиск запрещен:` / run / wpa_supplicant': отказано в разрешении / usr / share / нечто / usr / игры / что-то
Однако вы можете перенаправить стандартную ошибку на стандартный вывод, и тогда grep обработает текст обоих:
найти / -name '* что-то *' 2> & 1 | grep 'что-то'
/ usr / поделиться / doc / что-то / usr / поделиться / doc / что-то / примеры / что-то случайное / usr / поделиться / что-то / usr / игры / что-то
Обратите внимание, что в приведенной выше команде дескриптор целевого файла ( 1 ) имеет префикс с амперсандом (« & »). Для получения дополнительной информации о перенаправлении потока данных см. Конвейеры в оболочке bash.
Примеры создания и использования файловых дескрипторов в bash см. В наших примерах встроенной команды exec.
Дескриптор файла, условия операционной системы