Какова продолжительность жизни файлового дескриптора?

11

Как описано здесь , перенаправления используются open()для записи в файл. В оболочке есть внутренний (?) Файловый дескриптор, который затем используется при необходимости.

Внутренний дескриптор создается на протяжении всего сценария или времени жизни оболочки? Разрушено ли оно через некоторое время, ряд операций и т.д?

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

#!/bin/bash
>>x echo something
...do many other things not related to the file x
>>x echo something more

Сохраняется ли первый экземпляр дескриптора до второй операции?

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

Джефф Шаллер
источник

Ответы:

4

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


Детали: Там нет явного упоминания о закрытии файлов, открытых через перенаправления в POSIX (насколько я вижу). Но не закрывать их немедленно не было бы очень полезно.

В правилах для окружающей среды , все команды , которые запускаются в не позволяют определять дополнительные дескрипторы файлов. Оболочке нужно будет позаботиться о том, чтобы закрыть все дополнительные файлы, которые были сохранены, при запуске команды, которая не должна иметь их.

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

Например, это не будет работать правильно, если для первого echoоткроется fd, а для второго будет использоваться как есть:

echo foo >> x; mv x y; echo bar >> x

Обычная модель fork + exec, используемая для запуска внешних программ, также позволяет очень легко автоматически закрывать файлы при выходе из команды. Оболочке нужно только fork()сначала и открыть все необходимые файлы в дочернем процессе, прежде чем вызывать exec()для замены дочернего элемента действительной командой. Когда дочерний процесс завершается, все открытые им файлы автоматически закрываются.


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

awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'
ilkkachu
источник
6

Они закрыты, когда закончите с. Оболочка создаст 3 файловых дескриптора 0,1,2 для каждой команды, которую она запускает. Это просто цифры, цифры используются повторно. Оболочка закроет файлы перед повторным использованием дескрипторов.

Файловые дескрипторы также передаются в другие процессы. И если у вас есть процесс в фоновом режиме, он все равно будет иметь файловые дескрипторы.

В 3>&1данном примере это означает, что дескриптор 3 файла ссылается на файл, к которому в настоящее время относится дескриптор 1.

Ctrl-Alt-Делор
источник