Ich vermute, dass das Warum viel mit der Vision / dem Design zu tun hat, das Unix (und folglich Linux) geprägt hat, und den Vorteilen, die sich daraus ergeben.
Kein Zweifel, es ist ein nicht zu vernachlässigender Leistungsvorteil, keinen zusätzlichen Prozess zu starten, aber ich denke, es steckt noch mehr dahinter: Early Unix hatte eine Metapher "Alles ist eine Datei", die einen nicht offensichtlichen, aber eleganten Vorteil hat, wenn man sich das ansieht es aus einer Systemperspektive und nicht aus einer Shell-Skriptperspektive.
Angenommen, Sie haben Ihr null
Befehlszeilenprogramm und /dev/null
den Geräteknoten. Von einer Shell-Scripting - Perspektive, das foo | null
ist Programm eigentlich wirklich nützlich und bequem , und foo >/dev/null
nimmt ein kleines bisschen länger kann zu geben und seltsam erscheinen.
Aber hier sind zwei Übungen:
Lassen Sie uns die Umsetzung des Programms in null
einem der vorhandenen Unix - Tools und /dev/null
- einfach: cat >/dev/null
. Getan.
Können Sie /dev/null
in Bezug auf implementieren null
?
Sie haben absolut Recht, dass der C-Code zum Verwerfen von Eingaben trivial ist. Daher ist es möglicherweise noch nicht klar, warum es nützlich ist, eine virtuelle Datei für die Aufgabe zur Verfügung zu haben.
Bedenken Sie: Fast jede Programmiersprache muss bereits mit Dateien, Dateideskriptoren und Dateipfaden arbeiten, da diese von Anfang an Teil des Unix-Paradigmas "Alles ist eine Datei" waren.
Wenn Sie nur Programme haben, die nach stdout schreiben, ist es dem Programm egal, ob Sie sie in eine virtuelle Datei umleiten, die alle Schreibvorgänge schluckt, oder eine Pipe in ein Programm, das alle Schreibvorgänge schluckt.
Wenn Sie nun Programme haben, die Dateipfade zum Lesen oder Schreiben von Daten verwenden (was die meisten Programme tun) - und diesen Programmen die Funktion "Leereingabe" oder "Ausgabe verwerfen" hinzufügen möchten -, ist dies /dev/null
kostenlos.
Beachten Sie, dass die Eleganz darin besteht, dass die Codekomplexität aller beteiligten Programme verringert wird. Für jeden allgemeinen, aber besonderen Verwendungszweck, den Ihr System als "Datei" mit einem tatsächlichen "Dateinamen" bereitstellen kann, kann Ihr Code das Hinzufügen eines benutzerdefinierten Befehls vermeiden -Line-Optionen und benutzerdefinierte Codepfade zu behandeln.
Gutes Software-Engineering hängt oft davon ab, gute oder "natürliche" Metaphern zu finden, um ein Element eines Problems auf eine Weise zu abstrahieren, die leichter zu überlegen ist, aber dennoch flexibel bleibt , sodass Sie im Grunde die gleichen Probleme auf höherer Ebene lösen können, ohne dass dies erforderlich ist verbringen Sie die Zeit und die geistige Energie damit, Lösungen für dieselben Probleme auf niedrigerer Ebene ständig neu zu implementieren.
"Alles ist eine Datei" scheint eine solche Metapher für den Zugriff auf Ressourcen zu sein: Sie rufen open
einen bestimmten Pfad in einem hierarchischen Namespace auf, erhalten einen Verweis (Dateideskriptor) auf das Objekt, und Sie können read
und write
usw. auf die Dateideskriptoren. Ihre stdin / stdout / stderr sind auch Dateideskriptoren, die gerade für Sie vorab geöffnet wurden. Ihre Pipes sind nur Dateien und Dateideskriptoren, und mit der Dateiumleitung können Sie all diese Teile zusammenfügen.
Unix war ebenso erfolgreich wie Unix, da diese Abstraktionen gut zusammengearbeitet haben und /dev/null
am besten als Teil dieses Ganzen verstanden werden können.
PS: Es lohnt sich, sich die Unix-Version von "Alles ist eine Datei" anzuschauen, und zwar /dev/null
als erste Schritte zu einer flexibleren und leistungsfähigeren Verallgemeinerung der Metapher, die in vielen folgenden Systemen implementiert wurde.
Zum Beispiel mussten in Unix spezielle dateiähnliche Objekte wie /dev/null
im Kernel selbst implementiert werden, aber es hat sich herausgestellt, dass es nützlich genug ist, Funktionen in Datei- / Ordnerform bereitzustellen, die seitdem mehrere Systeme haben, die eine Möglichkeit für Programme bieten das zu tun.
Eines der ersten war das Betriebssystem Plan 9, das von einigen der gleichen Leute wie Unix entwickelt wurde. Später machte GNU Hurd mit seinen "Übersetzern" etwas Ähnliches. In der Zwischenzeit bekam Linux FUSE (das sich mittlerweile auch auf die anderen Mainstream-Systeme ausgebreitet hat).
cat foo | bar
viel schlimmer (im Maßstab) alsbar <foo
.cat
ist ein triviales Programm, aber selbst ein triviales Programm verursacht Kosten (von denen einige spezifisch für die FIFO-Semantik sind), da Programme nichtseek()
in FIFOs implementiert werden können Wenn eine Pipeline angegeben wird, kann sie mit einem Zeichengerät wie/dev/null
diesem diese Operationen vortäuschen oder mit einer echten Datei implementieren, aber ein FIFO lässt keine kontextbezogene Behandlung zu.