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

Bash-Befehlszeilen-Exit-Codes entmystifiziert

Wenn Sie einen Befehl ausführen oder ein Skript ausführen, erhalten Sie einen Exit-Code . Ein Exit-Code ist eine Systemantwort, die einen Erfolg, einen Fehler oder eine andere Bedingung meldet, die einen Hinweis darauf gibt, was ein unerwartetes Ergebnis Ihres Befehls oder Skripts verursacht hat. Möglicherweise erfahren Sie jedoch nie etwas über den Code, da sich ein Exit-Code nicht preisgibt, es sei denn, jemand fordert ihn dazu auf. Programmierer verwenden Exit-Codes, um ihren Code zu debuggen.

Hinweis: Sie sehen oft Exit-Code als Ausgangsstatus bezeichnet oder sogar als Ausgangsstatuscodes . Die Begriffe werden austauschbar verwendet, außer in der Dokumentation. Hoffentlich ist Ihnen meine Verwendung der beiden Begriffe klar.

Ich bin kein Programmierer. Es fällt mir schwer, das zuzugeben, aber es ist wahr. Ich habe sowohl formal als auch informell BASIC, FORTRAN und einige andere Sprachen studiert, und ich muss sagen, dass ich definitiv kein Programmierer bin. Oh sicher, ich kann ein wenig in PHP, Perl, Bash und sogar PowerShell Skripte schreiben und programmieren (ja, ich bin auch ein Windows-Administrator), aber ich könnte nie meinen Lebensunterhalt mit dem Programmieren verdienen, weil ich zu langsam beim Schreiben von Code bin und Trial-and-Error ist keine effiziente Debugging-Strategie. Es ist wirklich traurig, aber ich bin so kompetent darin, gefundenen Code zu kopieren und anzupassen, dass ich meine erforderlichen Aufgaben erfüllen kann. Und doch verwende ich auch Exit-Codes, um herauszufinden, wo meine Probleme liegen und warum etwas schief läuft.

[ Das könnte Ihnen auch gefallen:Ein kleiner Zauber zum Kopieren von SSH-Dateien in der Befehlszeile. ]

Exit-Codes sind bis zu einem gewissen Grad nützlich, können aber auch vage sein. Beispielsweise ist ein Exit-Code von 1 ein generischer Bucket für verschiedene Fehler und überhaupt nicht hilfreich. In diesem Artikel erkläre ich die Handvoll reservierter Fehlercodes , wie sie auftreten können und wie Sie sie verwenden, um herauszufinden, was Ihr Problem ist. Ein reservierter Fehlercode wird von Bash verwendet und Sie sollten keine eigenen Fehlercodes erstellen, die damit in Konflikt stehen.

Genug Hintergrundgeschichte. Es ist an der Zeit, sich Beispiele anzusehen, was Fehlercodes/Status generiert.

Extrahieren des schwer fassbaren Exit-Codes

Verwenden Sie den folgenden Befehl, um den Exit-Code für den letzten Befehl anzuzeigen, den Sie in der Befehlszeile ausgeführt haben:

$ echo $?

Die angezeigte Antwort enthält keinen Pomp oder Umstand. Es ist einfach eine Zahl. Möglicherweise erhalten Sie auch eine Shell-Fehlermeldung von Bash, die den Fehler weiter beschreibt, aber der Exit-Code und der Shell-Fehler zusammen sollten Ihnen dabei helfen, herauszufinden, was schief gelaufen ist.

Ausgangsstatus 0

Ein Exit-Status von 0 ist im Allgemeinen das bestmögliche Szenario. Es teilt Ihnen mit, dass Ihr letzter Befehl oder Ihr letztes Skript erfolgreich ausgeführt wurde. Der Erfolg ist relativ, da der Exit-Code Sie nur darüber informiert, dass das Skript oder der Befehl ordnungsgemäß ausgeführt wurde, aber der Exit-Code sagt Ihnen nicht, ob die darin enthaltenen Informationen einen Wert haben. Beispiele veranschaulichen besser, was ich beschreibe.

Listen Sie beispielsweise Dateien in Ihrem Home-Verzeichnis auf. Ich habe nichts in meinem Home-Verzeichnis außer versteckten Dateien und Verzeichnissen, also gibt es hier nichts zu sehen, aber der Exit-Code kümmert sich um nichts anderes als um den Erfolg der Befehlsausführung:

$ ls
$ echo $?
0

Der Exit-Code von 0 bedeutet, dass der ls Befehl lief ohne Probleme. Auch hier bieten mir die Informationen aus dem Exit-Code keinen wirklichen Wert.

Führen Sie nun ls aus Befehl auf /etc Verzeichnis und zeigen Sie dann den Exit-Code an:

$ ls /etc
**Many files**
$ echo $?
0

Sie können sehen, dass jede erfolgreiche Ausführung zu einem Exit-Code von 0 führt, einschließlich etwas, das völlig falsch ist, wie z. B. das Ausgeben des cat Befehl für eine ausführbare Binärdatei wie ls Befehl: 

$ cat /usr/bin/ls
**A lot of screen gibberish and beeping**
$ echo $?
0

Ausgangsstatus 1

Verwenden Sie das obige Beispiel, aber fügen Sie die lange Auflistung und rekursive Optionen hinzu (-lR ), erhalten Sie einen neuen Exit-Code von 1:

$ ls -lR /etc
**A lengthy list of files**
$ echo $?
1

Obwohl die Ausgabe des Befehls so aussieht, als ob alles gut gelaufen wäre, sehen Sie beim Scrollen nach oben mehrere Fehler "Berechtigung verweigert" in der Liste. Diese Fehler führen zu einem Exit-Status von 1, was als "unzulässige Vorgänge" bezeichnet wird. Obwohl Sie vielleicht erwarten, dass der Fehler „Berechtigung verweigert“ zu einem Exit-Status von 1 führt, liegen Sie falsch, wie Sie im nächsten Abschnitt sehen werden.

Eine Division durch Null ergibt jedoch einen Exit-Status von 1. Sie erhalten außerdem eine Fehlermeldung von der Shell, die Sie darüber informiert, dass die von Ihnen durchgeführte Operation "unzulässig:"

ist
$ let a=1
$ let b=0
$ let c=a/b
-bash: let: c=a/b: division by 0 (error token is "b")
$ echo $?
1

Ohne einen Shell-Fehler ist ein Exit-Status von 1 nicht sehr hilfreich, wie Sie am ersten Beispiel sehen können. Im zweiten Beispiel wissen Sie, warum Sie den Fehler erhalten haben, weil Bash es Ihnen mit einer Shell-Fehlermeldung mitteilt. Wenn Sie einen Exit-Status von 1 erhalten, suchen Sie im Allgemeinen nach unzulässigen Vorgängen (Berechtigung verweigert Nachrichten) gemischt mit Ihren Erfolgen (z. B. das Auflisten aller Dateien unter /etc , wie im ersten Beispiel in diesem Abschnitt).

Ausgangsstatus 2

Wie oben erwähnt, führt eine Shell-Warnung „Permission denied“ zu einem Exit-Status von 2 statt 1. Um sich das selbst zu beweisen, versuchen Sie, Dateien in /root aufzulisten :

$ ls /root
ls: cannot open directory '/root': Permission denied
$ echo $?
2

Exit-Status 2 wird angezeigt, wenn ein Berechtigungsproblem oder ein fehlendes Schlüsselwort in einem Befehl oder Skript vorliegt. Ein Beispiel für ein fehlendes Schlüsselwort ist das Vergessen, ein done hinzuzufügen im do eines Skripts Schleife. Die beste Methode zum Debuggen von Skripts mit diesem Exit-Status besteht darin, Ihren Befehl in einer interaktiven Shell abzusetzen, um die erhaltenen Fehler anzuzeigen. Diese Methode zeigt im Allgemeinen, wo das Problem liegt.

Berechtigungsprobleme sind etwas weniger schwierig zu entschlüsseln und zu debuggen als andere Arten von Problemen. Das einzige, was "Berechtigung verweigert" bedeutet, ist, dass Ihr Befehl oder Skript versucht, eine Berechtigungsbeschränkung zu verletzen.

Ausgangsstatus 126

Exit-Status 126 ist ein interessanter Berechtigungsfehlercode. Der einfachste Weg, um zu demonstrieren, wann dieser Code erscheint, besteht darin, eine Skriptdatei zu erstellen und zu vergessen, dieser Datei Ausführungsberechtigungen zu erteilen. Hier ist das Ergebnis:

$ ./blah.sh
-bash: ./blah.sh: Permission denied
$ echo $?
126

Dieses Berechtigungsproblem ist kein Zugriffsproblem, sondern eines der Einstellung, wie im Modus. Um diesen Fehler zu beseitigen und stattdessen einen Exit-Status von 0 zu erhalten, geben Sie chmod +x blah.sh aus .

Hinweis: Sie erhalten einen Exit-Status von 0, auch wenn die ausführbare Datei keinen Inhalt hat. Wie bereits erwähnt, ist "Erfolg" offen für Interpretationen.

Ich erhalte einen Exit-Status von 126. Dieser Code sagt mir eigentlich, was falsch ist, im Gegensatz zu den vagen Codes.

Ausgangsstatus 127

Exit-Status 127 sagt Ihnen, dass eines von zwei Dingen passiert ist: Entweder ist der Befehl nicht vorhanden oder der Befehl befindet sich nicht in Ihrem Pfad ($PATH ). Dieser Code wird auch angezeigt, wenn Sie versuchen, einen Befehl auszuführen, der sich in Ihrem aktuellen Arbeitsverzeichnis befindet. Beispielsweise befindet sich das obige Skript, dem Sie die Ausführungsberechtigung erteilt haben, in Ihrem aktuellen Verzeichnis, aber Sie versuchen, das Skript auszuführen, ohne anzugeben, wo es sich befindet:

$ blah.sh
-bash: blah.sh: command not found
$ echo $?
127

Wenn dieses Ergebnis in einem Skript auftritt, versuchen Sie, der problematischen ausführbaren Datei oder dem Skript den expliziten Pfad hinzuzufügen. Die Rechtschreibung zählt auch bei der Angabe einer ausführbaren Datei oder eines Skripts.

[ Den Lesern hat es auch gefallen:10 grundlegende Linux-Befehle, die Sie kennen müssen. ]

Ausgangsstatus 128

Der Exit-Status 128 ist die Antwort, die empfangen wird, wenn beim Programmieren ein Out-of-Range-Exit-Code verwendet wird. Aus meiner Erfahrung ist es nicht möglich, den Exit-Status 128 zu erzeugen. Ich habe mehrere Aktionen als Beispiel ausprobiert, aber ich kann es nicht umsetzen. Ich kann jedoch einen Exit-Status 128-Adjacent-Code erzeugen. Wenn Ihr Exit-Code 256 überschreitet, ist der zurückgegebene Exit-Status Ihr Exit-Code abzüglich 256. Dieses Ergebnis klingt seltsam und kann tatsächlich zu einem falschen Exit-Status führen. Sehen Sie sich die Beispiele an, um sich selbst davon zu überzeugen.

Erstellen Sie mit einem Exit-Code von 261 einen Exit-Status von 5:

$ bash
$ exit 261
exit
$ echo $?
5

Um einen fehlerhaften Exit-Status von 0 zu erzeugen:

$ bash
$ exit 256
exit
$ echo $?
0

Wenn Sie 257 als Exit-Code verwenden, ist Ihr Exit-Status 1 und so weiter. Wenn der Exit-Code eine negative Zahl ist, ist der resultierende Exit-Status diese Zahl subtrahiert von 256. Wenn Ihr Exit-Code also 20 ist, dann ist der Exit-Status 236.

Beunruhigend, nicht wahr? Die Lösung besteht für mich darin, die Verwendung von Exit-Codes zu vermeiden, die reserviert und außerhalb des Bereichs liegen. Der richtige Bereich ist 0-255.

Ausgangsstatus 130

Wenn Sie ein Programm oder Skript ausführen und Strg + C drücken, um es zu stoppen, lautet Ihr Exit-Status 130. Dieser Status lässt sich leicht demonstrieren. Geben Sie ls -lR / aus und drücken Sie dann sofort Strg-C:

$ ls -lR /
**Lots of files scrolling by**
^C
$ echo $?
130

Mehr gibt es zu diesem nicht zu sagen. Es ist kein sehr nützlicher Exit-Status, aber hier ist er zu Ihrer Information.

Exit-Status 255

Dieser endgültige reservierte Ausgangsstatus ist einfach zu erzeugen, aber schwer zu interpretieren. Die Dokumentation, die ich gefunden habe, besagt, dass Sie den Exit-Status 255 erhalten, wenn Sie einen Exit-Code verwenden, der außerhalb des Bereichs 0–255 liegt.

Ich habe festgestellt, dass dieser Status auch auf andere Weise hergestellt werden kann. Hier ist ein Beispiel:

$ ip
**Usage info for the ip command**
  
$ echo $?
255

Einige unabhängige Behörden sagen, dass 255 ein allgemeiner Fehlercode ist. Diese Aussage kann ich weder bestätigen noch dementieren. Ich weiß nur, dass ich den Exit-Status 255 erzeugen kann, indem ich bestimmte Befehle ohne Optionen ausführe.

[Verwandter Artikel: 10 weitere grundlegende Linux-Befehle, die Sie kennen müssen. ]

Abschluss

Da haben Sie es:Eine Übersicht über die reservierten Exit-Statusnummern, ihre Bedeutung und wie Sie sie generieren. Mein persönlicher Rat ist, immer die Berechtigungen und Pfade für alles zu überprüfen, was Sie ausführen, insbesondere in einem Skript, anstatt sich auf Exit-Statuscodes zu verlassen. Meine Debug-Methode besteht darin, dass ich, wenn ein Befehl in einem Skript nicht richtig funktioniert, den Befehl einzeln in einer interaktiven Shell ausführe. Diese Methode funktioniert viel besser, als ausgefallene Taktiken mit Unterbrechungen und Ausstiegen auszuprobieren. Ich gehe diesen Weg, weil meine Fehler (meistens) mit Berechtigungen zusammenhängen, also wurde ich darauf trainiert, dort zu beginnen.

Viel Spaß beim Überprüfen Ihres Status, und jetzt ist es Zeit für mich, zu beenden.

[ Möchten Sie Red Hat Enterprise Linux ausprobieren? Laden Sie es jetzt kostenlos herunter. ]


Linux
  1. Unterschied zwischen ' und ' in der Befehlszeile (bash)??

  2. Wie wertet Bash folgenden Code aus?

  3. 5 Standardvervollständigung Verfügbar in der Linux Bash-Befehlszeile

  4. Bash-Eingabeaufforderung mit letztem Exit-Code

  5. Exit-Code der Variablenzuweisung zur Befehlsersetzung in Bash

So löschen Sie den BASH-Befehlszeilenverlauf in Linux

Bash-Wartebefehl

Bash Exit-Befehl und Exit-Codes

Bash-printf-Befehl

So zeigen Sie den Bash-Verlauf ohne Zeilennummern an

Bash wenn auf einer einzigen Zeile