On 2023-03-20, Christian Weisgerber <
na...@mips.inka.de> wrote:
>> Normalerweise ist der Exitcode ja zwischen 0 und 255. Gibt es
>> Szenarien, in denen ein andere gewollt vorkommt?
>
> Traditionell können Schnittstellen wie wait() einfach keine größeren
> Werte zurückliefern. Mehr als acht Bit sind dafür nicht vorhanden.
Ich möchte das noch etwas weiter ausführen:
An der Schnittstelle zum Kernel übermittelt die Familie der wait()-
Funktionen zwei sich gegenseitig ausschließende Arten, wie ein Prozess
beendet wurde:
- Der Prozess hat sich selbst beendet und einen konkreten Rückgabewert
(Exit-Status) geliefert, der einen Wert zwischen 0 und 255 haben
kann.
- Der Prozess wurde durch ein Signal beendet und zwar konkret durch
Signal <soundso>.
Eine Prozess, der durch ein Signal beendet wurde, hat also prinzip-
bedingt keinen Rückgabewert.
Wenn nun eine _Shell_ im Spiel ist, dann verändert sich dieses
Modell. Die Shell kann nur einen Rückgabewert weiterreichen. Sie
hat keinen Mechanismus, um eine andere Prozessbeendigung zu vermitteln.
Nehmen wir ein minimales Shellskript:
#!/bin/sh
/bin/sleep 100
Die Shell führt mit fork() und exec() /bin/sleep aus und wartet auf
die Beendigung dieses Prozesses. Terminiert der Prozess normal,
gibt sie dessen Rückgabewert dann als Rückgabewert des Skripts
zurück.
Was aber geschieht, wenn der Prozess durch ein Signal beendet wurde?
Einfach 0 zurückgeben wie bei einer fehlerfreien Ausführung wäre
schlecht. Deshalb gibt es die Konvention, dass bei durch ein Signal
beendeten Prozessen die Shell als Rückgabewert 128 plus die Nummer
des Signals liefert. Sagen wir, während obiges Skipt läuft, will
ich nicht länger warten und tippe ^C. Der Terminaltreiber schickt
darauf ein SIGINT (Signal 2), das den sleep-Prozess abbricht. Das
Skript liefert als Rückgabewert 130 (128 + 2).
Grundsätzlich könnte ein Prozess sich auch normal beenden und einen
Rückgabewert von 130 liefern. Das ist bei von der Shell durchgereichten
Rückgabewerten nicht unterscheidbar.
Wenn die Shell einen Befehl nicht ausführen kann, weil sie ihn nicht
findet, dann liefert sie einen Rückgabewert von 127. Auch hier
könnte das grundsätzlich ein von einem Prozess selbst gelieferter
Wert sein. Sinnvollerweise bleibt man also bei Werten, die man mit
exit() zurückgibt, freiwillig im Bereich 0 bis 126.
Der vermeintliche Rückgabewert 256, der Marcos Frage ausgelöst hat,
ist durch interne Verarbeitung in xdm(8) entstanden, wie ich nebenan
in .x11 erklärt habe. Eine interne Funktion fasst die Prozessbeendigung
zu einem Gesamtwert Signal * 256 + Rückgabewert zusammen. D.h. der
Prozess wurde durch Signal 1 (SIGHUP) beendet. Eine Shell hätte hier
einen Rückgabewert von 129 (128 + 1) geliefert.