GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Gibt es unter Linux standardmäßige Exit-Statuscodes?

'1' :Catch-all für allgemeine Fehler

'2' :Missbrauch von Shell-Builtins (laut Bash-Dokumentation)

'126' :Der aufgerufene Befehl kann nicht ausgeführt werden

'127' :"Befehl nicht gefunden"

'128' :Ungültiges Argument zum Beenden

'128+n' :Fatal-Error-Signal "n"

'130' :Skript beendet durch Strg + C

'255' :Exit-Status außerhalb des Bereichs

Dies ist für Bash. Für andere Anwendungen gibt es jedoch andere Exit-Codes.


Teil 1:Erweiterter Bash-Skriptleitfaden

Wie immer enthält der Advanced Bash Scripting Guide großartige Informationen:(Dies wurde in einer anderen Antwort verlinkt, jedoch mit einer nicht kanonischen URL.)

1: Catchall für allgemeine Fehler
2: Missbrauch von Shell-Builtins (laut Bash-Dokumentation)
126: Der aufgerufene Befehl kann nicht ausgeführt werden
127: "Befehl nicht gefunden"
128: Ungültiges Argument zum Beenden
128+n: Fatal-Error-Signal "n"
255: Exit-Status außerhalb des Bereichs (Exit akzeptiert nur Integer-Argumente im Bereich 0 - 255)

Teil 2:sysexits.h

Das ABSG verweist auf sysexits.h .

Unter Linux:

$ find /usr -name sysexits.h
/usr/include/sysexits.h
$ cat /usr/include/sysexits.h

/*
 * Copyright (c) 1987, 1993
 *  The Regents of the University of California.  All rights reserved.

 (A whole bunch of text left out.)

#define EX_OK           0       /* successful termination */
#define EX__BASE        64      /* base value for error messages */
#define EX_USAGE        64      /* command line usage error */
#define EX_DATAERR      65      /* data format error */
#define EX_NOINPUT      66      /* cannot open input */    
#define EX_NOUSER       67      /* addressee unknown */    
#define EX_NOHOST       68      /* host name unknown */
#define EX_UNAVAILABLE  69      /* service unavailable */
#define EX_SOFTWARE     70      /* internal software error */
#define EX_OSERR        71      /* system error (e.g., can't fork) */
#define EX_OSFILE       72      /* critical OS file missing */
#define EX_CANTCREAT    73      /* can't create (user) output file */
#define EX_IOERR        74      /* input/output error */
#define EX_TEMPFAIL     75      /* temp failure; user is invited to retry */
#define EX_PROTOCOL     76      /* remote error in protocol */
#define EX_NOPERM       77      /* permission denied */
#define EX_CONFIG       78      /* configuration error */

#define EX__MAX 78      /* maximum listed value */

8 Bit des Rückgabecodes und 8 Bit der Nummer des Tötungssignals werden bei der Rückgabe von wait(2) zu einem einzigen Wert gemischt &Co..

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>

int main() {
    int status;

    pid_t child = fork();
    if (child <= 0)
        exit(42);
    waitpid(child, &status, 0);
    if (WIFEXITED(status))
        printf("first child exited with %u\n", WEXITSTATUS(status));
    /* prints: "first child exited with 42" */

    child = fork();
    if (child <= 0)
        kill(getpid(), SIGSEGV);
    waitpid(child, &status, 0);
    if (WIFSIGNALED(status))
        printf("second child died with %u\n", WTERMSIG(status));
    /* prints: "second child died with 11" */
}

Wie bestimmen Sie den Exit-Status? Traditionell speichert die Shell nur einen 8-Bit-Rückgabecode, setzt aber das High-Bit, wenn der Prozess abnormal beendet wurde.

$ sh -c 'exit 42'; echo $?
42
$ sh -c 'kill -SEGV $$'; echo $?
Segmentation fault
139
$ expr 139 - 128
11

Wenn Sie etwas anderes sehen, hat das Programm wahrscheinlich einen SIGSEGV Signalhandler, der dann exit aufruft normalerweise, also wird es nicht wirklich durch das Signal getötet. (Programme können beliebige Signale außer SIGKILL verarbeiten und SIGSTOP .)


Keine der älteren Antworten beschreibt den Exit-Status 2 korrekt. Im Gegensatz zu dem, was sie behaupten, ist Status 2 das, was Ihre Befehlszeilenprogramme tatsächlich zurückgeben, wenn sie unsachgemäß aufgerufen werden. (Ja, eine Antwort kann neun Jahre alt sein, Hunderte positive Stimmen erhalten und trotzdem falsch sein.)

Hier ist die echte, langjährige Ausgangsstatus-Konvention für die normale Terminierung, d. h. nicht per Signal:

  • Exit-Status 0:Erfolg
  • Ausgangsstatus 1:"Fehler", wie vom Programm definiert
  • Exit-Status 2:Fehler bei der Verwendung der Befehlszeile

Beispiel:diff gibt 0 zurück, wenn die verglichenen Dateien identisch sind, und 1, wenn sie sich unterscheiden. Nach langjähriger Konvention geben Unix-Programme den Ausgangsstatus 2 zurück, wenn sie falsch aufgerufen werden (unbekannte Optionen, falsche Anzahl von Argumenten usw.) Beispiel:diff -N , grep -Y oder diff a b c ergeben alle $? auf 2 gesetzt. Dies ist und war die Praxis seit den Anfängen von Unix in den 1970er Jahren.

Die akzeptierte Antwort erklärt, was passiert, wenn ein Befehl durch ein Signal beendet wird. Kurz gesagt, die Beendigung aufgrund eines nicht abgefangenen Signals führt zum Austrittsstatus 128+[<signal number> . Z. B. Terminierung durch SIGINT (Signal 2) ergibt Exit-Status 130.

Notizen

  1. Mehrere Antworten definieren den Exit-Status 2 als "Missbrauch von Bash-Builtins". Dies gilt nur, wenn bash (oder ein Bash-Skript) wird mit Status 2 beendet. Betrachten Sie es als Sonderfall eines Fehlers bei falscher Verwendung.

  2. In sysexits.h , erwähnt in der beliebtesten Antwort, Exit-Status EX_USAGE ("Kommandozeilen-Nutzungsfehler") ist auf 64 definiert. Dies entspricht jedoch nicht der Realität:Mir ist kein bekannt allgemeines Unix-Dienstprogramm, das bei falschem Aufruf 64 zurückgibt (Beispiele willkommen). Ein sorgfältiges Lesen des Quellcodes zeigt, dass sysexits.h ist ehrgeizig und spiegelt nicht die tatsächliche Verwendung wider:

     *    This include file attempts to categorize possible error
     *    exit statuses for system programs, notably delivermail
     *    and the Berkeley network.
    
     *    Error numbers begin at EX__BASE [64] to reduce the possibility of 
     *    clashing with oth­er exit statuses that random programs may 
     *    already return. 
    

    Mit anderen Worten, diese Definitionen spiegeln nicht die damals (1993) gängige Praxis wider, sondern waren mit dieser bewusst unvereinbar. Schade.


Linux
  1. Gibt es ein Programm wie COM0COM unter Linux?

  2. Gibt es STDCALL unter Linux?

  3. Gibt es C-APIs, um den Basisdateinamen aus seinem vollständigen Pfad in Linux zu extrahieren?

  4. Gibt es Optionen, um cat mit Farbe ausgeben zu lassen?

  5. Gibt es eine Möglichkeit, LD_PRELOAD und LD_LIBRARY_PATH unter Linux zu blockieren?

Mit Fedora 36 könnte es einen neuen Goldstandard für Linux-Distributionen geben

Gibt es ein WinSCP-Äquivalent für Linux?

Gibt es eine Möglichkeit, 64-Bit-time_t in 32-Bit-Programmen unter Linux zu erhalten?

Warum gibt es unter Linux so viele /dev/tty?

Gibt es moderne Linux-Distributionen, die /dev/audio noch unterstützen?

Gibt es GUIs für Linux, die X11 nicht verwenden?