Jaka jest żywotność deskryptora pliku?

11

Jak opisano tutaj , przekierowania służą open()do zapisu do pliku. W powłoce utworzono wewnętrzny (?) Deskryptor pliku, który jest używany w razie potrzeby.

Czy wewnętrzny deskryptor jest tworzony przez cały czas trwania skryptu lub czas życia powłoki? Czy po pewnym czasie ulegnie zniszczeniu, wielu operacjom itp.?

Mam na myśli w szczególności deskryptory plików dla plików, które sama powłoka otwiera dla swoich wbudowanych operacji. Czy deskryptor jest tworzony, a plik otwierany dla każdej operacji? Jak długo są przechowywane? Przykład:

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

Czy pierwsza instancja deskryptora jest przechowywana do drugiej operacji?

Co z powłoką, której używam w terminalu? Czasami jedna sesja jest otwarta przez kilka dni, a może nawet tygodni. Czy nadal zachowuje deskryptory wszystkich plików, na których operowałem przy użyciu wbudowanych powłok?

Jeff Schaller
źródło

Odpowiedzi:

4

W skrócie: powłoka prawie na pewno zamknie deskryptory plików związane z przekierowaniami natychmiast po zakończeniu polecenia.


Szczegóły: Nie ma wyraźnej wzmianki o zamykaniu plików otwieranych przez przekierowania w POSIX (o ile widzę). Ale nie zamknięcie ich natychmiast nie byłoby bardzo przydatne.

Te zasady dla środowiska wszelkie polecenia są uruchamiane w nie pozwalają na przekazywanie dodatkowych deskryptorów plików. Powłoka będzie musiała zadbać o zamknięcie wszelkich dodatkowych zapisanych fd, które zostały zapisane podczas uruchamiania polecenia, które nie powinno ich mieć.

W przypadku zwykłych > filenameprzekierowań wyjściowych plik musiałby zostać obcięty podczas uruchamiania każdej komendy, nawet jeśli deskryptor pliku został zapisany. A każdy zapisany deskryptor pliku wskazywałby na niewłaściwy plik, jeśli nazwa tego pliku zostałaby w międzyczasie zmieniona lub usunięta.

Na przykład nie działałoby to poprawnie, gdyby fd otwarty dla pierwszego echobył otwarty i użyty jako taki jest dla drugiego:

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

Zwykły model fork + exec używany do uruchamiania programów zewnętrznych również bardzo ułatwia automatyczne zamykanie plików po wyjściu polecenia. Powłoka musi tylko fork()najpierw otworzyć i otworzyć wszystkie niezbędne pliki w procesie potomnym, zanim zadzwoni, exec()aby zastąpić dziecko rzeczywistym poleceniem. Po zakończeniu procesu potomnego wszystkie otwarte przez niego pliki są automatycznie zamykane.


Wawk , choć składnia przekierowania wyjścia jest podobny do muszli, ale wszelkie otwarte pliki przechowywane są otwarte aż do zjazdu skryptu, chyba że wyraźnie zamknięte. To otworzy się tylko fooraz i nie skróci go między wydrukami:

awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'
ilkkachu
źródło
6

Po zakończeniu są zamknięte. Powłoka utworzy 3 deskryptory plików 0,1,2 dla każdego uruchamianego polecenia. To tylko liczby, liczby są ponownie używane. Powłoka zamknie pliki przed ponownym użyciem deskryptorów.

Deskryptory plików są również przekazywane do innych procesów. A jeśli masz proces w tle, nadal będzie miał deskryptory plików.

W tym przykładzie użyto 3>&1oznaczenia, aby deskryptor pliku 3 odwoływał się do pliku, do którego obecnie odwołuje się deskryptor 1.

ctrl-alt-delor
źródło