it-swarm.com.de

Was sind die Min- und Max-Werte von Exit-Codes unter Linux?

Was sind die Min- und Max-Werte der folgenden Exit-Codes unter Linux:

  1. Der von einer ausführbaren Binärdatei zurückgegebene Exit-Code (z. B. ein C-Programm).
  2. Der von einem Bash-Skript zurückgegebene Exit-Code (beim Aufruf von exit).
  3. Der von einer Funktion zurückgegebene Exit-Code (beim Aufruf von return). Ich denke das ist zwischen 0 und 255.
45
user271801

Die an den Systemaufruf _exit()/exit_group() übergebene Nummer (manchmal auch als Exit-Code bezeichnet, um die Mehrdeutigkeit mit zu vermeiden Exit-Status , der sich auch auf eine Codierung des Exit-Codes oder der Signalnummer und zusätzliche Informationen bezieht, je nachdem, ob der Prozess normal beendet oder beendet wurde) ist vom Typ int, also auf Unix-ähnlichen Systemen wie Linux, normalerweise eine 32-Bit-Ganzzahl mit Werten von -2147483648 (-231) bis 2147483647 (231-1).

Wenn jedoch auf allen Systemen der übergeordnete Prozess (oder der untergeordnete Subreaper oder init, wenn der übergeordnete Prozess gestorben ist) wait(), waitpid(), wait3() verwendet, wait4() Systemaufrufe zum Abrufen, nur die unteren 8 Bits davon sind verfügbar (Werte 0 bis 255 (2)8-1)).

Bei Verwendung der API waitid() (oder eines Signalhandlers unter SIGCHLD) auf den meisten Systemen (und wie POSIX jetzt in der Ausgabe 2016 des Standards deutlicher erfordert (siehe _exit() Spezifikation )) ist die vollständige Nummer verfügbar (im Feld si_status Der zurückgegebenen Struktur). Dies ist unter Linux jedoch noch nicht der Fall, wodurch die Zahl mit der waitid() - API ebenfalls auf 8 Bit gekürzt wird, obwohl sich dies wahrscheinlich in Zukunft ändern wird.

Im Allgemeinen möchten Sie nur die Werte 0 (im Allgemeinen Erfolg) bis 125 verwenden, da viele Shells Werte über 128 in ihrer $? - Darstellung des Exit-Status verwenden , um die Signalnummer eines abgebrochenen Prozesses und 126 und 127 für spezielle Bedingungen zu codieren.

Möglicherweise möchten Sie 126 bis 255 für exit() verwenden, um dasselbe zu bedeuten wie für $? Der Shell (wie wenn ein Skript ret=$?; ...; exit "$ret" Ausführt). Die Verwendung von Werten außerhalb von 0 -> 255 ist im Allgemeinen nicht sinnvoll. Dies tun Sie im Allgemeinen nur, wenn Sie wissen, dass das übergeordnete Element die API waitid() auf Systemen verwendet, die nicht abgeschnitten werden, und Sie zufällig den 32-Bit-Wertebereich benötigen. Beachten Sie, dass wenn Sie beispielsweise exit(2048) ausführen, dies von den Eltern unter Verwendung der herkömmlichen wait*() - APIs als Erfolg angesehen wird.

Weitere Infos unter:

Diese Fragen und Antworten sollten hoffentlich die meisten Ihrer anderen Fragen beantworten und klarstellen, was unter Exit-Status zu verstehen ist. Ich werde noch ein paar Dinge hinzufügen:

Ein Prozess kann nur beendet werden, wenn er beendet wurde oder die Systemaufrufe _exit()/exit_group() aufruft. Wenn Sie von main() in C zurückkehren, ruft die libc diesen Systemaufruf mit dem Rückgabewert auf.

Die meisten Sprachen haben eine exit() - Funktion, die diesen Systemaufruf umschließt, und den Wert, den sie annehmen, falls vorhanden, wird im Allgemeinen so wie er ist an den Systemaufruf übergeben. (Beachten Sie, dass diese im Allgemeinen mehr Dinge tun, wie die Bereinigung durch die exit() - Funktion von C, die die Standardpuffer löscht und die atexit() - Hooks ausführt ...)

Das ist zumindest der Fall bei:

$ strace -e exit_group awk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ strace -e exit_group mawk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ strace -e exit_group busybox awk 'BEGIN{exit(1234)}'
exit_group(1234)                        = ?
$ echo | strace -e exit_group sed 'Q1234'
exit_group(1234)                        = ?
$ strace -e exit_group Perl -e 'exit(1234)'
exit_group(1234)                        = ?
$ strace -e exit_group python -c 'exit(1234)'
exit_group(1234)                        = ?
$ strace -e exit_group expect -c 'exit 1234'
exit_group(1234)                        = ?
$ strace -e exit_group php -r 'exit(1234);'
exit_group(1234)                        = ?
$ strace -e exit_group zsh -c 'exit 1234'
exit_group(1234)

Sie sehen gelegentlich einige, die sich beschweren, wenn Sie einen Wert außerhalb von 0-255 verwenden:

$ echo 'm4exit(1234)' | strace -e exit_group m4
m4:stdin:1: exit status out of range: `1234'
exit_group(1)                           = ?

Einige Muscheln beschweren sich, wenn Sie einen negativen Wert verwenden:

$ strace -e exit_group dash -c 'exit -1234'
dash: 1: exit: Illegal number: -1234
exit_group(2)                           = ?
$ strace -e exit_group yash -c 'exit -- -1234'
exit: `-1234' is not a valid integer
exit_group(2)                           = ?

POSIX lässt das Verhalten undefiniert, wenn der an das spezielle integrierte exit übergebene Wert außerhalb von 0-> 255 liegt.

Einige Muscheln zeigen unerwartete Verhaltensweisen, wenn Sie Folgendes tun:

  • bash (und mksh, aber nicht pdksh, auf dem es basiert) nimmt es auf sich, den Wert auf 8 Bit zu kürzen:

    $ strace -e exit_group bash -c 'exit 1234'
    exit_group(210)                         = ?
    

    Wenn Sie in diesen Shells mit einem Wert außerhalb von 0-255 beenden möchten, müssen Sie Folgendes tun:

    exec zsh -c 'exit -- -12345'
    exec Perl -e 'exit(-12345)'
    

    Das heißt, Sie führen einen anderen Befehl im selben Prozess aus, mit dem den Systemaufruf mit dem gewünschten Wert aufrufen kann.

  • wie in diesen anderen Fragen und Antworten erwähnt, hat ksh93 das seltsamste Verhalten für Exit-Werte von 257 bis 256 + max_signal_number, wobei es sich anstelle des Aufrufs von exit_group() mit dem entsprechenden Signal¹ selbst tötet.

    $ ksh -c 'exit "$((256 + $(kill -l STOP)))"'
    zsh: suspended (signal)  ksh -c 'exit "$((256 + $(kill -l STOP)))"'
    

    und schneidet ansonsten die Zahl wie bash/mksh ab.


¹ Dies wird sich jedoch wahrscheinlich in der nächsten Version ändern. Jetzt, da die Entwicklung von ksh93 Als Gemeinschaftsmaßnahme außerhalb von AT & T übernommen wurde, dieses Verhalten wird, obwohl es von POSIX irgendwie gefördert wird, rückgängig gemacht

77

Das Minimum ist 0, und das ist der Erfolgswert. Alle anderen sind gescheitert. Das Maximum ist 255 auch bekannt als -1.

Diese Regeln gelten sowohl für Skripte und andere ausführbare Dateien als auch für Shell-Funktionen.

Größere Werte ergeben Modulo 256.

12
user147505

Das sieht so einfach aus, aber oh, das Leid.

Die C-Sprache (und die meisten anderen Sprachen direkt oder indirekt) erfordert, dass die Rückgabe von main dem Aufruf von exit mit demselben Argument wie der Rückgabewert entspricht. Dies ist eine Ganzzahl (der Rückgabetyp ist sehr eindeutig int), daher würde der Bereich im Prinzip INT_MIN bis INT_MAX sein.

POSIX gibt an dass nur die untersten 8 Bits, die an exit übergeben werden, einem wartenden übergeordneten Prozess zur Verfügung gestellt werden sollen, buchstäblich so, als wäre es "status & 0xFF".
In der Praxis ist der Exit-Code also eine (noch vorzeichenbehaftete) Ganzzahl, von der nur die niedrigsten 8 Bits gesetzt sind.

Das Minimum ist somit -128 und das Maximum 127. Warte, das stimmt nicht. Es wird 0 bis 255 sein.

Aber leider kann es natürlich nicht so einfach sein . In der Praxis ist Linux (oder besser gesagt Bash) macht es anders . Der gültige Bereich von Rückkehrcodes liegt zwischen 0 und 255 (d. H. Ohne Vorzeichen).

Um auf der sicheren Seite zu sein, um Verwirrung zu vermeiden, ist es wahrscheinlich eine gute Idee, einfach anzunehmen, dass die Rückkehrcodes nicht signiert sind, und alles, was Sie von wait zurückerhalten, in nicht signiert umzuwandeln . Auf diese Weise stimmt es mit dem überein, was Sie in einer Shell sehen. Da die obersten Bits (einschließlich des höchstwertigen) gelöscht werden, ist dies nicht einmal "falsch", da die tatsächlichen Werte, obwohl technisch vorzeichenbehaftet, immer vorzeichenlos sind (da das Vorzeichenbit niemals gesetzt wird).
Es hilft auch, den häufigen Fehler beim Vergleichen eines Exit-Codes mit -1 zu vermeiden, der aus irgendeinem seltsamen Grund niemals erscheint, selbst wenn ein Programm mit beendet wird -1 (raten Sie mal, warum!).

Zu Ihrem letzten Punkt, der von einer Funktion zurückkehrt, wenn diese Funktion zufällig main ist, siehe oben. Andernfalls hängt es vom Rückgabetyp der Funktion ab, es könnte im Prinzip alles sein (einschließlich void).

6
Damon
  1. Der von einer ausführbaren Binärdatei zurückgegebene Exit-Code (z. B. ein C-Programm).
  2. Der von einem Bash-Skript zurückgegebene Exit-Code (beim Aufruf von exit).

Exit-Codes aus jedem Prozess - ob es sich um eine ausführbare Binärdatei, ein Shell-Skript oder etwas anderes handelt - reichen von 0 bis 255. Es ist möglich, einen größeren Wert an exit() zu übergeben, aber nur die unteren 8 Bits des Status werden anderen Prozessen über wait() zur Verfügung gestellt.

  1. Der von einer Funktion zurückgegebene Exit-Code (beim Aufruf von return). Ich denke das ist zwischen 0 und 255.

Eine C-Funktion kann als Rückgabe fast aller Typen deklariert werden. Die Grenzen seines Rückgabewerts werden vollständig von diesem Typ bestimmt: zum Beispiel -128 bis 127 für eine Funktion, die signed char Zurückgibt, oder 0 bis 4,2 Milliarden für eine Funktion, die unsigned int Zurückgibt, oder eine beliebige Floating-Funktion -Punktnummer bis einschließlich inf für eine Funktion, die double zurückgibt. Und das zählt nicht die nicht numerischen Typen wie void * Oder ein struct...

2