Was ist die Lebensdauer eines Dateideskriptors?


11

Wie hier beschrieben , werden Umleitungen open()zum Schreiben in eine Datei verwendet. In der Shell wird ein innerer (?) Dateideskriptor erstellt, der bei Bedarf verwendet wird.

Wird der innere Deskriptor für die gesamte Dauer des Skripts oder die Lebensdauer der Shell erstellt? Wird es nach einiger Zeit, einer Reihe von Operationen usw. zerstört?

Ich meine insbesondere Dateideskriptoren für die Dateien, die die Shell selbst für die Operationen ihrer eingebauten Dateien öffnet. Wird der Deskriptor erstellt und die Datei für jede Operation geöffnet? Wie lange werden sie aufbewahrt? Beispiel:

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

Wird die erste Deskriptorinstanz bis zur zweiten Operation beibehalten?

Was ist mit der Shell, die ich in einem Terminal verwende? Ich halte manchmal eine Sitzung tagelang, vielleicht sogar wochenlang offen. Behält es immer noch die Deskriptoren für alle Dateien, die ich mit integrierten Shell-Dateien bearbeitet habe?

Antworten:


4

Kurz gesagt: Eine Shell schließt mit ziemlicher Sicherheit Dateideskriptoren, die sich auf Umleitungen beziehen, unmittelbar nach Abschluss des Befehls.


Details: Es wird nicht ausdrücklich erwähnt, dass die durch Umleitungen in POSIX geöffneten Dateien geschlossen werden (soweit ich sehen kann). Aber sie nicht sofort zu schließen, wäre nicht sehr nützlich.

Die Regeln für die Umgebung, in der Befehle gestartet werden, erlauben keine Übergabe zusätzlicher Dateideskriptoren. Die Shell müsste darauf achten, alle zusätzlichen FDs zu schließen, die sie gespeichert hat, wenn ein Befehl gestartet wird, der sie nicht haben sollte.

Für die üblichen > filenameAusgabeausleitungen müsste die Datei für den Fall, dass jeder Befehl gestartet wird, abgeschnitten werden, selbst wenn der Dateideskriptor gespeichert wurde. Und jeder gespeicherte Dateideskriptor würde auf eine falsche Datei verweisen, wenn die betreffende Datei in der Zwischenzeit umbenannt oder entfernt würde.

Dies würde sich beispielsweise nicht korrekt verhalten, wenn das für das erste echogeöffnete fd offen gehalten und für das zweite unverändert verwendet würde:

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

Das übliche fork + exec-Modell zum Starten externer Programme macht es auch sehr einfach, die Dateien beim Beenden des Befehls automatisch zu schließen. Die Shell muss nur fork()zuerst alle erforderlichen Dateien im untergeordneten Prozess öffnen, bevor sie aufruft exec(), um das untergeordnete Element durch den eigentlichen Befehl zu ersetzen. Wenn der untergeordnete Prozess beendet wird, werden alle von ihm geöffneten Dateien automatisch geschlossen.


Inawk aber ist die Syntax für die Umleitung der Ausgabe auf die Schale ähnlich, aber alle geöffneten Dateien werden geöffnet , bis das Script beendet gehalten, sofern nicht explizit geschlossen. Dies wird nur fooeinmal geöffnet und auch zwischen den Ausdrucken nicht abgeschnitten:

awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'

6

Sie sind geschlossen, wenn Sie fertig sind. Die Shell erstellt für jeden ausgeführten Befehl 3 Dateideskriptoren 0,1,2. Dies sind nur Zahlen, die Zahlen werden wiederverwendet. Die Shell schließt die Dateien, bevor die Deskriptoren wiederverwendet werden.

Dateideskriptoren werden auch an andere Prozesse übergeben. Und wenn Sie einen Prozess im Hintergrund haben, hat er immer noch Dateideskriptoren.

In diesem Beispiel 3>&1bedeutet dies, dass Dateideskriptor 3 auf die Datei verweist, auf die sich Deskriptor 1 derzeit bezieht.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.