HOWTO zum Exit-Status von Kommandos
===================================
(C) 2006-2026 T.Birnthaler/H.Gottschalk <howtos(at)ostc.de>
OSTC Open Source Training and Consulting GmbH
www.ostc.de
$Id: shell-exit-code-HOWTO.txt,v 1.11 2026/06/09 17:19:15 tsbirn Exp $
Dieses Dokument beschreibt die Bedeutung des Shell-Exit-Status und seine
Nutzung in Shell-Skripten, um den Ablauf in Abhängigkeit vom Ergebnis eines
Kommandos zu steuern.
Jedes Kommando (jeder Prozess) gibt am Ende einen "Exit-Status" (kleiner Wert
im Bereich 0-255) zurück, über den es seinem Elternprozeß mitteilt, ob es
korrekt ablief oder ob ein Fehler auftrat.
+------------+--------------------------------------------------------+
| Code | Bedeutung |
+------------+--------------------------------------------------------+
| 0 | Kommando lief korrekt ab |
| ungleich 0 | Bei der Ausführung des Kommandos trat ein FEHLER auf |
| | (Wert kann die FEHLERART beschreiben, muss aber nicht) |
+------------+--------------------------------------------------------+
HINWEIS: Die Bedeutung der einzelnen Exit-Fehlercodes ist von Kommando zu
Kommando VERSCHIEDEN und kann in der jeweiligen man-Page nachgelesen werden
(nach dem Begriff "exit status" suchen, er wird oft erst am Ende erläutert).
Der Exit-Status kann NUR DIREKT NACH einem Kommando abgefragt und über das
Kommando "test" für Verzweigungen des Programmflusses benutzt werden. Er steht
auch in der Shell-Variablen "$?" (bzw. "$status" bei der (t)csh) und kann
darüber ausgegeben werden. Beispiele:
grep TEXT FILE # 0 falls TEXT (Muster) in FILE gefunden
# 1 falls TEXT (Muster) in FILE nicht gefunden
# 2 falls FILE nicht vorhanden oder TEXT (Muster) fehlerhaft
echo $? # Exit-Status ausgeben (nur 1x sinnvoll, da "echo" auch Kmdo.)
echo $? # Exit-Status von vorherigem "echo" (Wert "0" da erfolgreich)
grep TEXT FILE # 0 falls TEXT (Muster) in FILE gefunden
ES=$? # Exit-Status in Variable ES speichern (für mehrfachen Vgl.)
Da für die Shell der Wert 0 "logisch wahr" bedeutet und alle anderen Werte 1,
2, ... für sie "logisch falsch" bedeuten, kann über den Exit-Status eines Tests
per "[...]" oder "test" der Ablauf eines Shell-Skriptes gesteuert werden:
[ -f /tmp/text ] && echo "Datei '/tmp/text' existiert"
[ -d /tmp/dir ] || echo "Verzeichnis '/tmp/dir' existiert nicht"
Da jedes Kommando/Programm/Skript einen Exit-Status erzeugt, kann sein Erfolg
anschließend sofort überprüft und entsprechend reagiert werden (die
Fehlermeldungen per "echo" wird dabei auf "stderr" (1>&2) ausgegeben):
grep "error:" /tmp/log > /dev/null && echo "Fehler in Log gefunden" 1>&2
mv text /tmp || echo "Datei 'text' nicht verschiebbar" 1>&2
chmod a+w log || echo "Rechte von Datei 'log' nicht änderbar" 1>&2
if grep "error:" /tmp/log > /dev/null
then
echo "$(grep -c "error:" /tmp/log > /dev/null) Fehler in Log gefunden"
else
echo "Alles in Ordnung"
fi
Meist interessiert in einem Shell-Skript die Ausgabe eines Kommandos überhaupt
nicht, sondern nur der Exit-Status. D.h. beim Kommando-Aufruf wirft man alle
Ausgaben per Umleitung mit einer der folgenden drei Möglichkeiten weg:
if grep "error:" /tmp/log > /dev/null 2> /dev/null; ...
if grep "error:" /tmp/log > /dev/null 1>&2; ...
if grep "error:" /tmp/log >& /dev/null; ...
Die Shell (bash, ksh) selbst kennt zwei Exit-Status mit denen sie den
fehlgeschlagenen Aufruf eines Kommandos kommuniziert:
+-------------+-------------------------------------------------+
| Exit-Status | Bedeutung |
+-------------+-------------------------------------------------+
| 126 | Kommando gefunden, aber nicht lesbar/ausführbar |
| 127 | Kommando nicht gefunden |
+-------------+-------------------------------------------------+
Beim Abbruch eines Kommandos per SIGNAL wird die Signal-Nummer + 128 als
Exit-Status zurückgegeben:
+----------------+------------+---------+---------------+
| ES = 128 + Sig | Bedeutung | Name | Steuerzeichen |
+----------------+------------+---------+---------------+
| 129 = 128 + 1 | Hangup | SIGHUP | Strg-D |
| 130 = 128 + 2 | Interrrupt | SIGINT | Strg-C |
| 131 = 128 + 3 | Quit | SIGQUIT | |
| 134 = 128 + 6 | Abort | SIGABRT | |
| 137 = 128 + 9 | Kill | SIGKILL | |
| 138 = 128 + 10 | User 1 | SIGUSR1 | |
| 140 = 128 + 12 | User 2 | SIGUSR2 | |
| 141 = 128 + 13 | Pipe | SIGPIPE | |
| 142 = 128 + 14 | Alarm | SIGALRM | |
| 143 = 128 + 15 | Terminate | SIGTERM | |
| 145 = 128 + 17 | Child | SIGCHLD | |
| 146 = 128 + 18 | Continue | SIGCONT | Strg-Q |
| 147 = 128 + 19 | Stop | SIGSTOP | Strg-S |
| 148 = 128 + 20 | Typed Stop | SIGTSTP | Strg-Z |
+----------------+------------+---------+---------------+