Nicht-Null-Ausgangsstatus für einen sauberen Ausgang

15

Ist es akzeptabel, einen Exit-Code ungleich Null zurückzugeben, wenn das betreffende Programm ordnungsgemäß ausgeführt wurde? Angenommen, ich habe ein einfaches Programm, das (nur) Folgendes ausführt:

Das Programm akzeptiert N Argumente. Es gibt einen Exit-Code von min (N, 255) zurück. Beachten Sie, dass jedes N für das Programm gültig ist.

Ein realistischeres Programm kann verschiedene Codes für erfolgreich ausgeführte Programme zurückgeben, die verschiedene Dinge bedeuten. Sollten diese Programme diese Informationen stattdessen in einen Stream schreiben, z. B. auf stdout?

Thomas Eding
quelle

Antworten:

24

Es hängt von der Umgebung ab, aber ich würde sagen, es ist ein schlechter Stil.

Unix-ähnliche Systeme haben die starke Konvention, dass ein Exit-Status von 0 Erfolg und ein Exit-Status ungleich Null Fehler bedeutet. Einige, aber nicht alle Programme unterscheiden zwischen verschiedenen Arten von Fehlern mit unterschiedlichen Exit-Codes ungleich Null. Beispielsweise wird in der grepRegel 0 zurückgegeben, wenn das Muster gefunden wurde, 1, wenn es nicht gefunden wurde, und 2 (oder mehr), wenn ein Fehler aufgetreten ist, z. B. eine fehlende Datei.

Diese Konvention ist ziemlich fest mit Unix-Shells verbunden. Zum Beispiel in sh, bashund anderen Bourne-wie Muscheln, die ifAnweisung behandelt einen 0 Exit - Status als Erfolg / true, und einen von Null verschiedenen Exit - Status als Ausfall / false:

if your-command
then
    echo ok
else
    echo FAILURE
fi

Ich glaube, dass die Konventionen unter MS Windows ähnlich sind.

Jetzt hindert Sie sicherlich nichts mehr daran, ein eigenes Programm zu schreiben, das unkonventionelle Exit-Codes verwendet, insbesondere wenn nichts anderes damit interagiert. Beachten Sie jedoch, dass Sie gegen eine gut eingeführte Konvention verstoßen, und es könnte später wiederkommen und Sie beißen .

Die übliche Art und Weise, wie ein Programm diese Art von Informationen zurückgibt, besteht darin, diese zu drucken stdout:

status = $(your-command)
echo Result is $status
Keith Thompson
quelle
7
+1 für die Erklärung der Konvention, würde dieser Ansatz die meisten meiner Shell-Skripte brechen, wenn ich set -eirgendwo ein platziere.
Benjamin Bannier
Analog dazu grepwird diff1 zurückgegeben, wenn Unterschiede gefunden werden. und> 1, wenn ein Fehler aufgetreten ist.
7heo.tk
6

Hängt davon ab, was Ihre Umgebung erwartet.

Mein Favorit für Seltsamkeit, aus Wikipedia :

In OpenVMS wird Erfolg durch ungerade Werte und Misserfolg durch gerade Werte angezeigt. Der Wert ist eine 32-Bit-Ganzzahl mit Unterfeldern: Steuerbits, Einrichtungsnummer, Nachrichtennummer und Schweregrad. Die Schweregrade werden zwischen Erfolg (Erfolg, Information) und Misserfolg (Warnung, Fehler, Schwerwiegend) aufgeteilt.

Rechnung
quelle
4

Ich denke, es gibt einen Präzedenzfall, wenn der Exit-Code aussagekräftige, relevante Informationen an den Aufrufer zurückgibt und die Definition des Erfolgs nicht wirklich binär ist. Der Präzedenzfall, an den ich denke, ist die Robokopie, die eine Menge verschiedener Dinge zurückgibt, je nachdem, was passiert ist .

Ich füge hinzu, dass wir aus diesem Grund immer ein wenig debuggen müssen - die meisten Hilfsprogramme gehen davon aus, dass der Exit-Code 0 == Erfolg hat. Es wird auch kein Fehler angezeigt.

Wyatt Barnett
quelle
2

Es ist eine schlechte Idee, für eine erfolgreiche Ausführung nicht 0 zurückzugeben, da dies zu Verwirrung bei denjenigen führen kann, die Ihr Programm ausführen. Was wäre, wenn einige Ihr Programm mehr als 100 Mal mit unterschiedlichen Eingaben ausgeführt hätten und wissen wollten, wie viele fehlgeschlagen oder erfolgreich abgeschlossen wurden. Ein einziger Erfolgswert macht es viel einfacher, Unterschiede zu erkennen, als viele unterschiedliche Werte.

Wenn Sie ein Programm haben, das mehrere erfolgreiche Rückkehrpfade hat, die alle verschiedene Dinge bedeuten können, würde ich sagen, dass dies ein Zeichen dafür ist, dass Ihr Programm schlecht entworfen ist.

Ryathal
quelle
2

Ich kenne einen Fall, den ich für akzeptabel halte. Ich kenne ein Test-Framework, das mit der Gesamtzahl der Testfehler endet. Wenn der Testläufer beispielsweise keine fehlgeschlagenen Tests durchführt, wird er mit Null beendet. Wenn ein Test fehlgeschlagen ist, obwohl der Testläufer selbst ordnungsgemäß ausgeführt wurde, wird er mit einer 1 beendet. Wenn zwei fehlgeschlagen sind, werden 2 usw. zurückgegeben. Dies ergibt bis zu 250, was "250 oder mehr Testfehler" bedeutet.

Es verwendet Exit-Codes> 250, um abnormale Exits anzuzeigen.

Obwohl dies gegen die Konvention verstößt, funktioniert es in der Praxis gut.

Bryan Oakley
quelle
3
Ich glaube nicht , das tut Konvention verletzt - Test ist erfolgreich , wenn keine Fehler vorhanden sind; Ein Ergebniscode ungleich Null zeigt fehlgeschlagene Tests an.
Bevan
1
Das bedeutet "Beenden mit einem Fehlerstatus, um mehr als 0 Fehler anzuzeigen" und obwohl dies möglicherweise die genaue allgemeine Semantik des Beendenstatus verletzt, verletzt es sicherlich nicht die Konvention "0 ist in Ordnung, alles, was größer als 0 ist, ist ein Fehler" .
Vatine
2

Es kommt wirklich darauf an, was Sie mit dem Code vermitteln wollen. DB2 gibt beispielsweise 100 zurück, wenn keine Daten gefunden wurden, sowie verschiedene andere positive Werte für Warnungen und negative Werte für Fehler. Oracle macht etwas Ähnliches.

Wenn es also unterschiedliche Erfolgszustände gibt, kann es sich lohnen, unterschiedliche Rückgabewerte zu verwenden.

Matthew Flynn
quelle
2

Ein gutes Beispiel: man sa-update (Spamassassin)

CODES BEENDEN

  • Ein Beendigungscode von 0 bedeutet, dass ein Update verfügbar war und erfolgreich heruntergeladen und installiert wurde, wenn --checkonly nicht angegeben wurde.
  • Ein Beendigungscode von 1 bedeutet, dass keine neuen Updates verfügbar waren.
  • Ein Exit-Code von 2 bedeutet ...

In diesem Fall ist Exit 1 einfach ein informativer Code. Wenn ich jedoch den Code geschrieben hätte, hätte ich nicht 1 gewählt, da dies normalerweise ein Netzausfall ist.

Evert
quelle