Fehlerströmung

Ich liebe Streams! Die Idee, dass man alles als Stream öffnen kann, Daten rausziehen und Daten reinstecken kann ist doch eigentlich genial.

Diese überlegene Unix-Konzept wurde zum Glück auch in Windows (zumeist) übernommen, und so bieten Dateien, Sockets, Pipes, Geräte, Treiber und auch Prozesse eine recht einheitliche Schnittstelle an, um Daten auszutauschen.

Man kann also mit den 2 Funkionen read() und write() bzw. ReadFile und WriteFile die halbe Welt erobern.
(Bei Windows sieht man schon am Namen, wie limitiert die API früher war, heute sind die beiden Funktion wesentlich mächtiger.)

Jetzt haben aber ausgerechnet Prozesse noch so einen zusätzlichen “halben” Stream, nämlich den STDERR. Die Standard Streams, die grundsätzlich jedem Prozess zur Verfügung stehen, lauten auf

  • STDIN: für die Dateneingabe (z.B. die Tastatur)
  • STDOUT: für die Datenausgabe (z.B. auf den Bildschirm)
  • STDERR: für die Datenausgabe von Fehlern.

Das ist zwar ein tolles Debugging-Feature, dass man Fehler wo anders rausschreiben kann, als korrekte Daten, aber es macht eben auch das allgemein gehaltene Stream-Konzept ein bisschen kaputt.

Das beginnt bei der Tatsache, dass viele Elternprozesse beim Schaffen ihrer Kinder den STDOUT und den STDERR auf das gleiche Medium setzen. Oder noch einfacher: Die Ausgabe ist immer der Bildschirm. Egal ob ein Prozess in STDOUT oder STDERR schreibt, es landet hintereinander auf der gleichen Mattscheibe.

Es wirkt asymetrisch, dass ein Prozess eine Eingabemöglichkeit und zwei Ausgabemöglichkeiten besitzt, denn das haben die meisten anderen Streams nämlich nicht.

Man hätte auch neben STDIN auch ein STDCTRL einführen können, dann hätten Prozesse eben 2 Streams, einen primären für Daten und einen sekundären für Sonderfälle.

Aber OK. Will man hingegen Prozesse steuern, muss man sich immer die Frage stellen, wie man mit dem STDERR umgehen will.

  • Setzt man STDOUT und STDERR auf die gleich pipe?
  • Deaktiviert man STDERR oder setzt es auf /dev/null?
  • Liest man STDERR und bietet die Daten separat an?
  • Liest man STDERR und kombiniert es mit STDOUT?

Das Problem ist, dass man das für jeden Prozess anders entscheiden kann, weil jeder Prozess STDERR anders einsetzt.

Ich kenne leider auch keine allgemeine Lösung und so bleibt mir im GATE Projekt auch nichts anderes übrig, als ein spezielles Process-Stream-Interface bereitzustellen, das neben dem üblichen read und write auch ein separates read_err beinhaltet.


Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!