Ist die Verwendung von FD 3 sicher?

Ist die Verwendung von FD 3 sicher?

Es gibt mehrere Fragen, die es verwenden, um beispielsweise mehrere Ausgabe-Pipes auszuführen, ohne Prozesssubstitution zu verwenden:

Ist es sicher, hierfür einfach eine feste FD-Nummer zu verwenden? Ist es möglich, dass ein Programm diese bereits wie beschrieben verwendet?Hierund wir überschreiben etwas Wichtiges oder lesen etwas, das damit nichts zu tun hat?

Antwort1

Ist es möglich, dass ein Programm es bereits verwendet?

Nein. Die E/A-Umleitung erfolgt, bevor ein Programm oder ein Skript gestartet wird.

Normalerweise sind beim Start eines Programms oder Skripts nur die Standarddeskriptoren (0/Standardeingabe, 1/Standardausgabe und 2/Standardfehler) geöffnet. (Sie können sich auf ein Terminal, ein Gerät, eine Datei oder sogar einen Netzwerksocket beziehen, aber es wird erwartet, dass sie geöffnet sind. Anstatt einen zu „schließen“, leiten wir einen unerwünschten Deskriptor von/nach um /dev/null, im Wesentlichen „nirgendwo“/„nichts“.)

Programme verwenden Deskriptoren über Systemaufrufe wie opendie einen freien Deskriptor verwenden. Das heißt, sie fordern den Kernel nicht auf, eine Datei oder einen Socket zu öffnenzu einem bestimmten Deskriptor, der Kernel wählt den Deskriptor. Der einzige Fall, in dem ein Programm einen zusätzlichen Deskriptor verwendet, ist, wenn erwartet wird, dass dieser beim Programmstart bereits geöffnet ist. Es gibt einige seltene Utility-Daemons wie diesen – zusätzlich zu den Standarddeskriptoren erwarten sie, dass, wenn z. B. Deskriptor 3 beim Start geöffnet ist, dieser mit ihrem Verwaltungsdienst (oder etwas Ähnlichem) verbunden ist.

Wenn ein Programm sich entscheidet, einen hartcodierten Deskriptor zu verwenden (und der einzige Grund dafür ist, dass es ein anderes Programm aufspaltet und ausführt, daserwartetdieser Deskriptor soll offen sein; wie ich sagte, das kommt sehr selten vor), der bereits offene Deskriptor wird geschlossen, wenn das Programm ihn durch das ersetzt, wofür es ihn gerade verwendet. (Der Kernel führt das Schließen übrigens durch, wenn das Programm angibt, dass es einen bestimmten Deskriptor verwenden möchte, z. B. dup2()in POSIXy-Systemen; der Prozess muss sich nicht darum kümmern.)

Shell-Skripte (Bash und sh) verwenden feste Deskriptornummern, daher ist es möglich, dass ein Skript einen bestimmten Deskriptor verwendet, um einige Eingabe-/Ausgabeumleitungen durchzuführen. Wenn dies jedoch geschieht, werden die vorherigen Umleitungen einfach ignoriert und haben keine Wirkung, da die Skripte davon ausgehen, dass der Deskriptor geschlossen wurde. (Wenn ein Deskriptor geöffnet ist und das Skript diesen Deskriptor für interne Dinge verwendet, wird der ursprüngliche Deskriptor zuerst geschlossen – vom Kernel und aus den im vorherigen Absatz genannten Gründen – wenn das Skript ihn umleitet. Damit es zu Datenlecks kommen kann, müsste das Skript speziellprüfenwenn ein Deskriptor bereits geöffnet ist undvermeidenumleiten.)

Beachten Sie auch, dass Fortran-E/A-Einheiten oder -Kanäle nicht mit Deskriptoren in Zusammenhang stehen, auch wenn beide eine Nummer zur Identifizierung verwenden. Selbst wenn ein Fortran-Programm also Einheit 10 verwendet, bedeutet das nicht, dass es Deskriptor 10 verwendet.

Ist es sicher, hierfür einfach eine feste FD-Nummer zu verwenden?

Ja. POSIX besagt, dass ein Programm mindestens 20 Deskriptoren geöffnet haben kann, daher sollte jede feste Zahl zwischen 3 und 19 problemlos funktionieren.

Der entscheidende Punkt ist eine gute Dokumentation, vorzugsweise in einem kurzen Kommentar am Anfang des Skripts (bei Skripten) oder in der Verwendungs- ( -hoder --helpBefehlszeilenoption) und Manpage (bei Programmen).

Bei Skripten können Sie davon ausgehen, dass Benutzer die feste Deskriptornummer ändern können, um sie ihren Bedürfnissen anzupassen, wenn ein Konflikt auftritt (und wenn dies der Fall ist, handelt es sich um einen Konflikt der Art „Skript funktioniert überhaupt nicht, weil die Pipe geschlossen wird, sobald das Programm gestartet wird“, wie oben beschrieben). Ihre Aufgabe als Skriptautor besteht also darin, vorauszuplanen und dies für diejenigen, die nach Ihnen kommen, einfacher zu machen. (Ein klarer Kommentar, der Ihre Absicht und das Gesamtdesign beschreibt, ist ausreichend; es ist nicht notwendig, die Deskriptornummer zu einer Variable zu machen oder jede kleine Aktion des Skripts zu beschreiben.)

Bei Programmen ist es sinnvoll, sie zur Laufzeit konfigurierbar zu machen. Sie könnten beispielsweise Ihr Programm/Ihren Daemon, wenn geöffnet, für ein spezielles Steuerprotokoll mit grafischer Benutzeroberfläche den Deskriptor 3 verwenden lassen; mit einer Befehlszeilenoption wie „-c 5“ jedoch den benannten Deskriptor verwenden (oder mit -c /dev/nameoder die angegebene Datei, benannte Pipe oder -c named-pipeden -c :socketpath lokalen Domänensocket verwenden). Auf diese Weise können Benutzer Konflikte mit Skripten problemlos umgehen.

verwandte Informationen