Wann wird der Standardfehlerstrom in der Befehlszeilenanwendung verwendet?

9

Gibt es eine Richtlinie, wann der Fehler beim Schreiben einer Befehlszeilenanwendung verwendet werden soll? Zu meiner Überraschung habe ich beim Googeln nichts gefunden.

Insbesondere ist die Frage, mit der ich mich gerade befasse, ob ich das Programm verwenden soll stdoutoder stderrwann der Benutzer das Programm mit illegalen Argumenten aufgerufen hat. Eine umfassendere Antwort wird jedoch sehr geschätzt, da dies sicherlich nicht der einzige Fall ist, in dem eine klare Regel erforderlich ist, um ein Programm zu schreiben, das sich so verhält, wie es vom Benutzer erwartet wird.

UTF-8
quelle
Ist es in Ordnung, dass diese Fehlermeldungen mit der regulären Ausgabe gemischt werden? Ist das Programm beispielsweise ein Filter für Daten?
Thrig
Es ist kein Filter für Daten. Es ist auch nicht interaktiv. Der Benutzer ruft es mit Argumenten auf (darunter Dateipfade), das Programm funktioniert, ändert diese Dateien, druckt einige Nachrichten, druckt im Idealfall keine Fehlermeldungen und beendet.
UTF-8

Antworten:

15

Ja, zeigen Sie eine Meldung an, stderrwenn die falschen Argumente verwendet werden. Wenn dies auch dazu führt, dass die Anwendung beendet wird, beenden Sie sie mit einem Exit-Status ungleich Null.

Sie sollten den Standardfehlerstrom für Diagnosemeldungen oder für die Benutzerinteraktion verwenden. Zu den Diagnosemeldungen gehören Fehlermeldungen, Warnungen und andere Meldungen, die nicht Teil der Ausgabe des Dienstprogramms sind, wenn es ordnungsgemäß funktioniert ("korrekt" bedeutet, dass nichts Außergewöhnliches passiert, z. B. nicht gefundene Dateien oder was auch immer).

Viele Shells (alle?) Zeigen Eingabeaufforderungen, die Benutzertypen, Menüs usw. an, stderrdamit die Umleitung Sie stdoutnicht daran hindert, auf sinnvolle Weise mit der Shell zu interagieren.

Folgendes stammt aus einem Blogbeitrag zu diesem Thema:

Dies ist ein Zitat von Doug McIllroy, Erfinder der Unix-Pipes, der erklärt, wie es dazu stderrkam. 'v6' bezieht sich auf eine Version einer bestimmten Version des ursprünglichen Unix-Betriebssystems, das 1975 veröffentlicht wurde.

Alle Programme stellten die Diagnose auf die Standardausgabe. Dies hatte immer zu Problemen geführt, wenn die Ausgabe in eine Datei umgeleitet wurde, wurde jedoch unerträglich, wenn die Ausgabe an einen ahnungslosen Prozess gesendet wurde. Da die Leute jedoch nicht bereit waren, die Einfachheit des Standard-Input-Standard-Output-Modells zu verletzen, tolerierten sie diesen Zustand durch Version 6. Kurz danach schnitt Dennis Ritchie den gordischen Knoten, indem er die Standardfehlerdatei einführte. Das war nicht genug. Bei Pipelines kann die Diagnose von mehreren Programmen gleichzeitig erfolgen. Diagnose erforderlich, um sich zu identifizieren.
- Doug McIllroy, "Ein Research UNIX Reader: Kommentierte Auszüge aus dem Programmierhandbuch, 1971-1986"

Sich zu identifizieren bedeutet einfach zu sagen "Hey! Ich rede! Das ging schief: [...]":

$ ls nothere
ls: nothere: No such file or directory

Dies zu tun stderrist vorzuziehen, da es sonst von dem gelesen werden könnte, was gerade gelesen wurde stdout(aber wir machen das lssowieso nicht , oder?).

Kusalananda
quelle
Wenn Sie dem Benutzer also etwas fragen, während die Anwendung ausgeführt wird, sollten Sie die Frage auf stderr drucken. Das klingt nicht richtig. Hast du eine Quelle dafür? Gilt dies nur für Anwendungen, deren Ausgabe nicht nur Fragen und Antworten enthält (Ausgabe, die der Benutzer möglicherweise irgendwo weiterleiten möchte)?
UTF-8
@ UTF-8 Sollte der Text der Frage als Teil der Ausgabe des Programms betrachtet werden? Was ist mit dem, was der Benutzer eingibt? Ich denke nicht, dass es sein sollte (genau wie Muscheln nicht denken, dass es sein sollte). Aber vielleicht kommt es auf die Anwendung an?
Kusalananda
1
Vielen Dank für Ihre Bearbeitung. In der Zwischenzeit habe ich das Verhalten von Standardanwendungen überprüft und sie verhalten sich so, als würde man erwarten, dass sie sich nach dem Lesen Ihrer Antwort verhalten.
UTF-8
@ UTF-8 Sie könnten diese Fragen und Antworten
terdon
5

Aus den POSIX-Spezifikationen für die Standard-Streams:

Beim Programmstart müssen drei Streams vordefiniert sein und müssen nicht explizit geöffnet werden: Standardeingabe (zum Lesen herkömmlicher Eingaben), Standardeingabe (zum Schreiben herkömmlicher Ausgaben) und Standardfehler (zum Schreiben diagnostischer Ausgaben ).

Mit anderen Worten, Fehler, Debugging-Informationen und alles, was in die Diagnosekategorie fällt, werden behandelt stderr.

Weitere Informationen finden Sie in der entsprechenden Frage: Gehören Fortschrittsberichte / Protokollierungsinformationen zu stderr oder stdout?

Sergiy Kolodyazhnyy
quelle