Wie erhalte ich die Liste der Beendigungscodes (und / oder Rückkehrcodes) und die Bedeutung für einen Befehl / ein Dienstprogramm?

16

Gibt es eine Möglichkeit, wie ich mit den Terminalbefehlen im Titel verfahren kann, oder muss ich die Codes überprüfen?

präzise
quelle

Antworten:

14

Es gibt kein "Rezept", um die Bedeutung eines Exit-Status eines bestimmten Terminalbefehls abzurufen.

Mein erster Versuch wäre die Manpage:

user@host:~# man ls 
   Exit status:
       0      if OK,

       1      if minor problems (e.g., cannot access subdirectory),

       2      if serious trouble (e.g., cannot access command-line argument).

Zweitens : Google . Siehe wget als Beispiel.

Drittens : Der Exit-Status der Shell, zum Beispiel bash. Bash und seine eingebauten Funktionen können speziell Werte über 125 verwenden. 127 für Befehl nicht gefunden, 126 für Befehl nicht ausführbar. Weitere Informationen finden Sie in den Bash-Exit-Codes .

Chaos
quelle
Ja, ein Mann, Info, ... Seiten enthalten sie ... und ich war besorgt um diejenigen, die es nicht taten. ..und ich weiß, eine Webrecherche ist immer eine Option. ..als jetzt scheint es, dass es nur die Bash-Exit-Codes waren, nach denen ich suchen musste ..
präzise
12

Exit - Codes weisen auf einen Fehlerzustand beim Beenden eines Programms hin und liegen zwischen 0 und 255. Die Shell und ihre eingebauten Funktionen können insbesondere die Werte über 125 verwenden, um bestimmte Fehlermodi anzuzeigen. Daher kann die Liste der Codes zwischen Shells und Betriebssystemen variieren (z. B. Bash verwendet den Wert 128 + N als Ausgangsstatus). Siehe: Bash - 3.7.5 Exit Status oder man bash.

Im Allgemeinen zeigt ein Null- Beendigungsstatus an, dass ein Befehl erfolgreich war , ein Nicht-Null- Beendigungsstatus zeigt einen Fehler an .

Um zu überprüfen, welcher Fehlercode vom Befehl zurückgegeben wird, können Sie $?nach dem Beenden eines Shell-Skripts den letzten Exit-Code drucken oder ${PIPESTATUS[@]}eine Liste der Exit-Statuswerte aus der Pipeline (in Bash) anzeigen.

Es gibt keine vollständige Liste aller Exit-Codes, die gefunden werden können. Es wurde jedoch versucht, die Exit-Statusnummern in der Kernel-Quelle zu systematisieren. Dies ist jedoch hauptsächlich für C / C ++ - Programmierer gedacht, und ein ähnlicher Standard für die Skripterstellung ist möglicherweise angebracht.

Eine Liste von Sysexits unter Linux und BSD / OS X mit bevorzugten Exit-Codes für Programme (64-78) finden Sie in /usr/include/sysexits.h(oder:man sysexits unter BSD):

0   /* successful termination */
64  /* base value for error messages */
64  /* command line usage error */
65  /* data format error */
66  /* cannot open input */
67  /* addressee unknown */
68  /* host name unknown */
69  /* service unavailable */
70  /* internal software error */
71  /* system error (e.g., can't fork) */
72  /* critical OS file missing */
73  /* can't create (user) output file */
74  /* input/output error */
75  /* temp failure; user is invited to retry */
76  /* remote error in protocol */
77  /* permission denied */
78  /* configuration error */
/* maximum listed value */

Die obige Liste weist zuvor nicht verwendete Beendigungscodes von 64 bis 78 zu. Der Bereich der nicht zugewiesenen Ausstiegscodes wird in Zukunft weiter eingeschränkt.

Die oben genannten Werte werden jedoch hauptsächlich in sendmail verwendet und von so gut wie niemand anderem verwendet, sodass sie nicht in der Nähe eines Standards liegen (wie von @Gilles angegeben ).

In der Shell lauten die Exit-Status wie folgt (basierend auf Bash):

  • 1- 125- Befehl wurde nicht erfolgreich abgeschlossen. Überprüfen Sie die Manpage des Befehls auf die Bedeutung des Status, einige Beispiele unten:

  • 1 - Abhilfe bei allgemeinen Fehlern

    Verschiedene Fehler, z. B. "Teilen durch Null" und andere unzulässige Operationen.

    Beispiel:

    $ let "var1 = 1/0"; echo $?
    -bash: let: var1 = 1/0: division by 0 (error token is "0")
    1
    
  • 2 - Missbrauch von Shell-Builtins (laut Bash-Dokumentation)

    Fehlendes Schlüsselwort oder Befehl oder Berechtigungsproblem (und Diff-Rückkehrcode bei einem fehlgeschlagenen Binärdateivergleich).

    Beispiel:

     empty_function() {}
    
  • 6 - Kein solches Gerät oder keine solche Adresse

    Beispiel:

    $ curl foo; echo $?
    curl: (6) Could not resolve host: foo
    6
    
  • 124 - Kommando läuft ab

  • 125- Wenn ein Befehl selbst fehlschlägt, siehe: coreutils
  • 126 - wenn der Befehl gefunden, aber nicht aufgerufen werden kann (zB nicht ausführbar)

    Berechtigungsproblem oder Befehl ist keine ausführbare Datei.

    Beispiel:

    $ /dev/null
    $ /etc/hosts; echo $?
    -bash: /etc/hosts: Permission denied
    126
    
  • 127 - Wenn ein Befehl nicht gefunden werden kann, gibt der zur Ausführung erstellte untergeordnete Prozess diesen Status zurück

    Mögliches Problem mit $PATHoder Tippfehler.

    Beispiel:

    $ foo; echo $?
    -bash: foo: command not found
    127
    
  • 128 - Ungültiges Argument an exit

    exit akzeptiert nur ganzzahlige Argumente im Bereich von 0 bis 255.

    Beispiel:

    $ exit 3.14159
    -bash: exit: 3.14159: numeric argument required
    
  • 128- 254- Schwerwiegendes Fehlersignal "n" - Befehl wurde aufgrund eines empfangenen Signals abgebrochen. Der Signalcode wird zu 128 (128 + SIGNAL) hinzugefügt, um den Status zu erhalten (Linux:, man 7 signalBSD:man signal Einige Beispiele:

  • 130 - Befehl abgebrochen, weil Strg-C gedrückt wurde, 130-128 = 2 (SIGINT)

    Beispiel:

    $ cat
    ^C
    $ echo $?
    130
    
  • 137- Wenn Befehl das KILL(9)Signal (128 + 9) gesendet wird , sonst der Beendigungsstatus des Befehls

    kill -9 $PPID der Schrift.

  • 141 - SIGPIPE - Schreiben auf einer Pfeife ohne Lesegerät

    Beispiel:

    $ hexdump -n100000 /dev/urandom | tee &>/dev/null >(cat > file1.txt) >(cat > file2.txt) >(cat > file3.txt) >(cat > file4.txt) >(cat > file5.txt)
    $ find . -name '*.txt' -print0 | xargs -r0 cat | tee &>/dev/null >(head /dev/stdin > head.out) >(tail /dev/stdin > tail.out)
    xargs: cat: terminated by signal 13
    $ echo ${PIPESTATUS[@]}
    0 125 141
    
  • 143 - Befehl mit Signalcode 15 beendet (128 + 15 = 143)

    Beispiel:

    $ sleep 5 && killall sleep &
    [1] 19891
    $ sleep 100; echo $?
    Terminated: 15
    143
    
  • 255* - Status außerhalb des Bereichs verlassen.

    exit akzeptiert nur ganzzahlige Argumente im Bereich von 0 bis 255.

    Beispiel:

    $ sh -c 'exit 3.14159'; echo $?
    sh: line 0: exit: 3.14159: numeric argument required
    255
    

Gemäß der obigen Tabelle haben die Exit-Codes 1 - 2, 126 - 165 und 255 eine spezielle Bedeutung und sollten daher für benutzerdefinierte Exit-Parameter vermieden werden.

Beachten Sie, dass Exit-Werte außerhalb des Bereichs zu unerwarteten Exit-Codes führen können (z. B. gibt Exit 3809 einen Exit-Code von 225, 3809% 256 = 225).

Sehen:

Kenorb
quelle
errnoWerte werden von System-APIs verwendet, sie werden nicht als Exit-Status verwendet (sie befinden sich nicht einmal im richtigen Bereich) und sind für Shell-Skripte irrelevant. Sysexits-Werte stammen von sendmail und werden von so gut wie niemand anderem verwendet. Sie sind nichts, was in der Nähe eines Standards liegt.
Gilles 'SO- hör auf böse zu sein'
7

Sie müssen sich den Code / die Dokumentation ansehen. Was einer "Standardisierung" jedoch am nächsten kommt, ist errno.h

Thorsten Staerk
quelle
Dank für die Header - Datei zeigen .. versucht in die Dokumentation von wenigen utils .. harte Zeit suchen , um die Exit - Codes zu finden, scheint die meisten werden die stderrs sein ...
präzise
3
errno.hist irrelevant, wenn es um Exit-Codes geht, nur um Fehlermeldungen.
Gilles 'SO - hör auf böse zu sein'
Die meisten Programme geben Beendigungscodes gemäß der BSD-Konvention aus sysexits.h. Einige Programme geben jedoch errnos zurück, und ich denke tatsächlich, dass das Zurückgeben von errnos am sinnvollsten ist. Nicht behandelte errnos breiten sich wie Ausnahmen nach oben aus (die Stays errno, Funktionen kehren z . B. -1oder zurück 0|NULL). Da Programme nur Funktionen sind, obwohl Funktionen in einem separaten Adressraum ausgeführt werden, ist es sinnvoll, dass ein Programm möglicherweise die errnoWeitergabe über die Prozessgrenze fortsetzen möchte .
PSkocik
@PSkocik, hast du ein Beispiel für einen solchen Befehl? Errnos sind nicht portierbar (Werte sind systemübergreifend nicht konsistent), und es gibt keine portierbare Möglichkeit, den Err-Namen oder die Fehlermeldung aus dem Wert abzurufen (zsh hat dafür eine integrierte Funktion). Ganz zu schweigen davon, dass einige Systeme Fehler über 123 aufweisen, die mit allgemeinen Fehlercodes von besonderer Bedeutung kollidieren würden . Normalerweise geben Befehle die Nachrichten aus der Fehlernummer aus und geben einen Erfolgs- / Fehler-Beendigungsstatus zurück. Befehle sind für Benutzer gedacht. Funktionen / Systemaufrufe sind für Programmierer gedacht.
Stéphane Chazelas
@StéphaneChazelas Ich habe es ein paar Mal gesehen, aber nicht in gut etablierten Programmen, muss ich zugeben. Ich habe in letzter Zeit persönlich errno + 1 in meinem Spielzeugsystem zurückgegeben (so dass 1 weiterhin "jeden Fehler" bedeutet), weil ich denke, dass das Serialisieren von Errno über die Prozessgrenze hinweg sinnvoller ist als das Übersetzen gemäß der BSD-Konvention, wie es bei Programmausführungen der Fall ist Im Wesentlichen Funktionsaufrufe und Funktionen verwenden errno. Ich benutze meinen eigenen Last-Exit-Status-Decoder in meinem PROMPT_COMMAND (bash), damit ich so etwas wie bekomme "($numeric_code|$bsd_decoded|$errno_plus_one_decoded)".
PSkocik
1

Soweit ich weiß, gibt es nur zwei mehr oder weniger Standardwerte - beide sind stdlib.hfür die Verwendung mit exit () definiert:

  • EXIT_SUCCESS (= 0)
  • EXIT_FAILURE (= 1)

Und der einzige de-facto-Standardwert, der für alle Programme der Welt dieselbe Bedeutung hat, ist 0 (Null), was für SUCCESS steht.

Verschiedene Programme führen unterschiedliche Listen der zurückgegebenen "Fehler" -Codes ein, um unterschiedliche Fehler (unterschiedliche Typen oder Schweregrade) zu unterscheiden oder hervorzuheben. Einige Programme verwenden den zurückgegebenen Wert sogar, um die ganzzahlige Anzahl der erkannten Laufzeitfehler zu melden (z. B. die Anzahl der fehlgeschlagenen Komponententests in der Klage).

Ich würde nicht empfehlen, irgendeine Art von "neuem Standard" einzuführen, der die stdlib.h

xoiss
quelle