'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
-
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.
-
In
sysexits.h
, erwähnt in der beliebtesten Antwort, Exit-StatusEX_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, dasssysexits.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 other 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.