Thomas Güttler guettliml@thomas-guettler.de (Do 05 Sep 2019 13:01:36 CEST):
Es ist für mich binär: Es war erfolgreich (keine Warnungen) oder es war nicht erfolgreich, dann gibt es (neben der Fehlermeldung) keinen Output (du nennst es Betriebsdaten).
http hat sich durchgesetzt. Da gibt es klare return-codes. Wenn man eine 200 bekommt, dann passt es und ich kann die Nutzdaten verarbeiten. Wenn ich zB eine 404 bekomme, dann weiß ich, dass in den Daten nur eine Fehlermeldung steht, also keine Betriebs/Nutzdaten.
Das verstehe ich jetzt nicht. Command Line Applications haben eine klare Konvention, was Return Codes angeht. Und es liegt an Dir, Daten, die auf STDOUT erscheinen, zu ignorieren und Daten auf STDERR dann als beschreibende Details zum Fehler zu verstehen.
Und es ist gut, daß diese Dinge nicht jeder selbst implementieren muss, sondern daß genau dafür die Shell da ist, die unerwünschte und nicht unterdrückbare Betriebsausgaben nach /dev/null schickt.
Also ich verstehe das Problem noch nicht. Die Unix-Idee mit der Shell gibt mir die Flexibilität und schränkt mich nicht ein.
Das ist etwa wie "Shell vs Programmiersprache". Bei der Shell gibt es eine Warnung auf stderr und dann wird lustig die nächste Zeile ausgewertet. Da werde ich zum Autist. So kann
Shell *ist* Programmiersprache. Was Du mit nächste Zeile meinst, weiß ich jetzt nicht, ob im Script oder bei der Verarbeitung der Daten. Die Shell¹ kennt „set -e“. Sehr nützlich.
ich keine zuverlässigen Produkte erstellen. Die Shell wird bei mir nur noch interaktiv verwendet. Wichtiger sind aber automatisierte Tests. Wenn es davon genug gibt, dann ist es eigentlich egal wie die Implementierung arbeitet.
Ob zuverlässig oder nicht, hängt sicher von der Aufgabenstellung ab. Ich denke, für Dein Eingangsproblem ist die Shell zuverlässig genug :)
Und ich erkenne nicht, wie diese zwei Ausgabekanäle Deine automatisierte Auswertung erschweren - im Gegenteil, sie wird vereinfacht, weil Du eben Betriebsdaten (die Du vielleicht nicht unterdrücken kannst) von anderen Daten trennt.
# C errno = 0; // to be safe int d = get_delta(); // how to declare failure? if (errno) perror("delta") # Perl $d = get_delta(); # return undef on failure, details in $@ if (not defined $d) { die $@ }; # Go d, err := get_delta() // return err != nil on error if err != nil { fmt.Fatal(err) }
Du schlägst gerade etwas vor, was dem von „C“ entspricht. (Nicht falsch verstehen, ich finde „C“ eine super Sprache, sollte jeder lernen, der was mit Programmieren tut.)
In meinem Kontext werden bei Fehlern in der Regel Exceptions geworfen.
Das „die()“ im Perl Beispiel kann wie eine Exception behandelt werden. In Go könnte man statt fmt.Fatal() mit panic() arbeiten, aber man hat da eine etwas andere Einstellung zu Fehlern. Nur die wirklichen „this should not happen“ sollten eine Panic erzeugen, andere sollten als diskreter Fehler an den Aufrufer zurückgeliefert werden. Aber das ist eine andere Baustelle als Dein Eingangsproblem, denke ich.
-- Heiko