Wann soll die Umleitung zum stderr in Shell-Skripten verwendet werden?


15

Ich weiß, dass gut erzogene Dienstprogramme wie grep "normale" Nachrichten an stdout und Fehlermeldungen an stderr ausgeben.

$ grep '^foo' file1 file2
file1:foo
grep: file2: No such file or directory

Wenn ich selbst Shell-Skripte schreibe, fällt es mir oft schwer zu entscheiden, welche Ausgabe und welche Nachrichten ich auf stderr präsentieren soll oder ob ich mich überhaupt darum kümmern soll.

Ich würde gerne etwas über bewährte Praktiken erfahren: Wann ist die Weiterleitung einer Nachricht an stderr erforderlich und sinnvoll, und wann nicht?

"Es kommt darauf an", klar, aber haben Sie einige Einsichten, die mir helfen würden, diese Entscheidungen zu treffen?

Um diese subjektive Frage auf das Format abzustimmen, möchte ich zu Antworten ermutigen, die das "Warum" ansprechen und durch Erfahrung und wenn möglich durch Fakten untermauert sind.


@ Ansturm erklärt es perfekt. Ich drucke normalerweise Fortschrittsberichte an stderr für lange Skripte.
Terdon

Antworten:


12

Wenn ich selbst Shell-Skripte schreibe, fällt es mir oft schwer zu entscheiden, welche Ausgabe und welche Nachrichten ich auf stderr präsentieren soll oder ob ich mich überhaupt darum kümmern soll.

Schweigen ist Gold. Gib nichts aus, wenn alles in Ordnung ist.

Ich würde gerne etwas über bewährte Praktiken erfahren: Wann ist die Weiterleitung einer Nachricht an stderr erforderlich und sinnvoll, und wann nicht?

Die einfachste Möglichkeit, stderr von stdout zu trennen: Stellen Sie sich vor, alle Ihre Skriptausgaben werden über eine Pipe an einen anderen Befehl umgeleitet. In diesem Fall sollten Sie alle Benachrichtigungen in stderr aufbewahren, da solche unerwarteten Informationen in stdout die Pipe-Sequenz unterbrechen können.

Auch manchmal in Pfeifen wie dieser:

command1 | while read line ; do command2 ; done | command3

Sie müssen etwas command2an die Benutzerausgabe übergeben. Der einfachste Weg ohne temporäre Dateien ist stderr.


Vielen Dank für die Idee "imagine a pipe". Manchmal habe ich Skripte implementiert, die nichts anderes tun als "benachrichtigen" ( echoeinige Variablen, zeigen, was getan wurde, zeigen den Fortschritt). Ich zögere, alles auf stderr zu setzen, da diese Protokollmeldungen alles sind, was das Skript jemals ausgeben wird. Ich bin nicht sicher, wie ich die Pipe-Idee in diesen Situationen anwenden soll.
glts

1
@glts Programme werden ständig modifiziert und verbessert. Während die von Ihnen erwähnten Skripte derzeit keine Daten ausgeben, können sie später oder als Ausgangspunkt für andere Skripte verwendet werden, die dies tun. Wenn Sie sich zunächst an die Konvention halten, werden Sie später viel weniger Überraschungen erleben. OTOH, wenn Sie nur die Ausgabe in einer Datei speichern möchten, müssen Sie stderr umleiten, so dass es ein Kompromiss wie alles andere ist.
Joe

+1 Eine weitere Umschreibung: Stellen Sie sicher, dass stdout immer maschinenlesbar ist oder zumindest nützliche Textdaten in einem einheitlichen Format enthält.
Tripleee

2

Ich schreibe in der Regel alles, was mit dem Anwendungsbetrieb zu tun hat stderr, stdoutist für Daten reserviert.

Stellen Sie sich eine Anwendung wie cat. Wenn Sie die Eingabe lesen und über eine Pipe an eine andere Anwendung übergeben, möchten Sie nicht, dass die Ausgabe mit Statusmeldungen übersät wird.

Alles, was für eine andere Bewerbung oder einen Postprozessor für meine Bewerbung interessant sein könnte, wird für stdoutalles verwendet, was sich nur auf die Interna meiner Bewerbung bezieht stderr.


0

Ich persönlich bevorzuge es, Fehlermeldungen und Ausnahmen stderrsowie Informationsnachrichten an zu senden stdout. IMO, stderrist für alle Ausnahmen und damit meine Konvention.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.