Gibt es eine offizielle POSIX-, GNU- oder andere Richtlinie, in der Fortschrittsberichte und Protokollinformationen (z. B. "Doing foo; foo done") gedruckt werden sollten? Persönlich neige ich dazu, sie an stderr zu schreiben, damit ich stdout umleiten und nur die tatsächliche Ausgabe des Programms erhalten kann. Mir wurde kürzlich gesagt, dass dies keine gute Praxis ist, da Fortschrittsberichte eigentlich keine Fehler sind und nur Fehlermeldungen an stderr gedruckt werden sollten.
Beide Positionen sind sinnvoll, und natürlich können Sie die eine oder die andere auswählen, je nachdem, was Sie im Detail tun, aber ich würde gerne wissen, ob es dafür einen allgemein akzeptierten Standard gibt. Ich konnte in POSIX, den GNU-Codierungsstandards oder anderen allgemein akzeptierten Listen mit Best Practices keine spezifischen Regeln finden.
Wir haben ein paar ähnliche Fragen, die sich jedoch nicht genau mit diesem Thema befassen:
Verwendung der Umleitung für stderr in Shell-Skripten : Die akzeptierte Antwort schlägt vor, was ich tendenziell tue, die endgültige Ausgabe des Programms auf stdout und alles andere auf stderr zu belassen. Dies wird jedoch nur als eine Meinung des Benutzers dargestellt, obwohl dies durch Argumente gestützt wird.
Sollte die Verwendungsmeldung an stderr oder stdout gehen? : Dies ist spezifisch für Hilfemeldungen, zitiert jedoch den GNU-Codierungsstandard. Dies ist die Art von Dingen, die ich suche, nur nicht auf Hilfemeldungen beschränkt.
Gibt es also offizielle Regeln, wo Fortschrittsberichte und andere informative Nachrichten (die nicht Teil der tatsächlichen Ausgabe des Programms sind) gedruckt werden sollen?
stdout
zusammen mit den Ergebnissen ist ein sicherer Weg, um die Ergebnisse unbrauchbar zu machen. Wenn Sie die Ergebnisse jemals an ein anderes Programm weiterleiten müssen, muss dieses Programm die Ergebnisse von den Spinnern trennen. Wenn Sie die Ausgabe in eine Datei umleiten, werden die Drehfelder nicht angezeigt. MEINER BESCHEIDENEN MEINUNG NACH.stdout
Genau wie Sato Katsura sagte, ist dies ein sicherer und richtiger Weg, um Spinner und andere informative Botschaften auszudrücken, aber wie viele Programmierer sagen, ist Schweigen Gold wert. Gib nichts aus, wenn alles in Ordnung ist. ' so in der Tat ist stderr immer verwendet wegen der vagen Definition zu tun, und auch das Rohr sequence.for kann brechen StdOut offiziellen Guidestderr
Fehlermeldungen zu melden, es sei denn, ein--verbose
Flag wird verwendet, und an diesem Punkt sind auch Fortschrittsberichte enthalten.Antworten:
Posix definiert die Standardströme somit :
Die GNU C Library beschreibt die Standard-Streams ähnlich:
Standarddefinitionen enthalten daher nur wenige Richtlinien für die Stream-Verwendung, die über die Standard- / Normalausgabe und die Diagnose- / Fehlerausgabe hinausgehen. In der Praxis ist es üblich, einen oder beide dieser Streams auf Dateien und Pipelines umzuleiten, bei denen Fortschrittsanzeigen ein Problem darstellen . Einige Systeme überwachen sogar die
stderr
Ausgabe und sehen dies als Anzeichen für Probleme an. Lediglich zusätzliche Fortschrittsinformationen sind daher in beiden Streams problematisch.Anstatt Fortschrittsanzeigen bedingungslos an einen der Standard-Streams zu senden , ist es wichtig zu erkennen, dass die Fortschrittsausgabe nur für interaktive Streams geeignet ist . Aus diesem Grund empfehle ich, Fortschrittszähler erst zu schreiben, nachdem Sie überprüft haben, ob der Stream interaktiv ist (z. B. mit
isatty()
) oder wenn er explizit über eine Befehlszeilenoption aktiviert wurde. Dies ist besonders wichtig für Fortschrittsanzeigen, bei denen das Aktualisierungsverhalten des Terminals sinnvoll ist, z. B.% -vollständige Balken.Für bestimmte sehr einfache Fortschrittsmeldungen ("Starten von X" ... "Fertig mit X") ist es sinnvoller, die Ausgabe auch für nicht interaktive Streams einzuschließen. In diesem Fall sollten Sie überlegen, wie Benutzer mit den Streams interagieren können, z. B. mit suchen, mit
grep
pagenless
oder mit überwachentail -f
. Wenn es sinnvoll ist, die Fortschrittsmeldungen in diesen Kontexten zu sehen, sind sie viel einfacher zu konsumierenstdout
.quelle
N% done
als auch an Dinge wiedoing foo
undfoo done
. Letztere sollten immer beibehalten werden, da sie beim Umleiten in eine Datei zum Debuggen verwendet werden. Ihr Vorschlag, zu überprüfen, ob der Stream interaktiv ist, ist daher nicht zutreffend (obwohl dies im Allgemeinen eine sehr gute Idee ist).curl
und sehenyum
. In diesem Fall würde ich darüber nachdenken, ob und wie der Benutzer mit der Ausgabe übergrep
oder überless
ähnliche Tools interagieren möchte .POSIX definiert Standardfehler als
Dies beschränkt die Verwendung nicht nur auf Fehlermeldungen. Ich würde Fortschrittsinformationen als Diagnoseausgabe betrachten, so dass sie zu Standardfehlern gehören.
quelle
stdout
standardmäßig zeilengepuffert, wohingegenstderr
es ungepuffert ist. Diesstderr
ist auch die natürliche Wahl für das Schreiben von Fortschritts-Text / Balken / Drehfeldern, die keine neue Zeile enthalten. (Wenn Sie einen solchen Text schreibenstdout
, müssen Sie Ihre Fortschrittsaufrufe überladenstdout.flush()
, um ihn sichtbar zu machen.)stdout
, müssen Sie auch spülen , wenn Ihr Text ist eine neue Zeile enthält , wenn Sie Ihre Fortschrittsberichte tatsächlich wollen in Echtzeit angezeigt, wenn umgeleitet.POSIX ist etwas konkreter in Bezug auf "Diagnoseinformationen" in Shell und Dienstprogrammen , 1.4: Standardwerte für Dienstprogrammbeschreibung (Schwerpunkt Mine):
IANASL, aber ich interpretiere das so, dass stderr nur ausgegeben wird, wenn das Dienstprogramm einen Fehler-Exit-Code zurückgibt. Da dies nicht der normale Ablauf für eine erfolgreiche Ausführung sein sollte, sollten von einem POSIX-Dienstprogramm keine Fortschrittsinformationen gedruckt werden, sofern kein Fehler auftritt (sofern natürlich nichts anderes angegeben ist usw.).
quelle
Nach dem Ausschlussprinzip kann es nur an stderr gehen. Ja, ich weiß, dass Sie nach einer offiziellen Spezifikation gefragt haben, die ich Ihnen nicht über den von Stephen Kitt angegebenen Link zur POSIX-Spezifikation hinaus vorstellen kann, der besagt, dass stderr für Diagnosezwecke bestimmt ist.
Der wichtigere Punkt ist, dass stdin und stdout eine Funktion haben, die das Drucken von Fortschrittsberichten für stdout nicht zulässt - sie bilden natürlich die Sequenz von Pipes, die in Unix-Shell-Befehlen nicht nur ein Nebeneffekt ist, sondern den Kern des leistungsstarken Pipelining-Ansatzes .
Damit. Auf stdout gehört nur die eigentliche "Nutzlast" Ihres Programms. Wenn Ihr Programm keine Ausgabe hat, sollte nichts auf stdout gehen. Dies lässt stderr für alles andere , einschließlich Fortschrittsberichte.
Zugegeben, dies hinterlässt eine Lücke - es wäre wahrscheinlich schön, ein "stdfluff" oder ähnliches zu haben, das weder für die Ausgabe noch für Fehler gedacht ist, sondern für Fortschrittsberichte, Debugging und ähnliches. Tatsächlich hindert Sie nichts daran, dies zu tun, dh Sie könnten Ihren Fortschritt in Dateideskriptor 3 ausgeben. Beispiel:
Dies erzeugt keine Ausgabe. (*)
Dies wird zu fd-3 gedruckt, das zu stdout umgeleitet wird.
(*) Das erste Beispiel erzeugt keine Ausgabe, ist aber noch etwas weit hergeholt. das
open
scheitert und$!
würde enthaltenno such file or directory
; Nehmen Sie dies nur als Beispiel, es ist natürlich nicht ernst gemeint, so verwendet zu werden. Wenn Sie in einem tatsächlichen Programm diese Route einschlagen möchten, können Sie testen, ob/dev/fd/3
es verwendbar ist, und dies als Hinweis darauf ansehen, ob Sie Ihre Fortschrittsberichte aktivieren möchten. Sie müssten das ziemlich früh tun, damit Sie nicht von Ihren eigenenopen
s für echte Dateien und so verwirrt werden ...quelle
fd-3
? Die dritte Diskette?Die Benutzungsnachricht sollte auf stdout gehen, wenn der Benutzer sie mit aufgerufen hat,
--help
und auf stderr, wenn er einen Fehler gemacht hat. Das bedingungslose Drucken auf stderr ist unangenehm, da es schwieriger ist, es mit einem Pager / grep / etc. Anzuzeigen.Darf ich auch einen dritten Weg vorschlagen: open / dev / tty für Fortschrittsberichte / Spinner / etc.
quelle
--help
oder helfe Nachrichten. Bitte lesen Sie die Frage erneut.