Bash wird bei abnormalem Beenden eines untergeordneten Prozesses aufgrund eines Signals nicht beendet

Bash wird bei abnormalem Beenden eines untergeordneten Prozesses aufgrund eines Signals nicht beendet

Ich gebe mir wirklich Mühe zu verstehen, was ich falsch mache und warum.

Ich habe ein launch.shSkript, das startet process.sh.

starten.sh

#!/bin/bash
while true; do 
./process.sh 
done

prozess.sh

#!/bin/bash
function signalHandler() {
    for i in {1..2}; do
        sleep 0.1s
        echo "process.sh: cleanup $i"
    done
    exit 130
}

trap "signalHandler" "SIGINT"

while true; do 
sleep 1s
done

wenn ich laufe

./launch.sh &

und dann töte es mit

kill -s SIGINT -$!    

wo $!bekommt man die PID des letzten Befehls (launch.sh) und das Minus sendet das Signal an alle Childs und fährt dann launch.shfort. Warum?


Ich habe das folgende Verhalten erwartet (laut diesem BlogSignal & Bash) :

launch.shDie Shell A mit dem im Hintergrund laufenden Skript wird unterbrochen, Bash wartet, bis process.shes fertig ist. Da process.shaufgrund des Signalhandlers in eine abnormale Rückkehr (Exit 130) erfolgt process.sh, sollte Shell A beendet werden. Warum wird sie nicht beendet?

Wenn der Status dieses untergeordneten Skripts anzeigt, dass es aufgrund dieses Signals abnormal beendet wurde, bereinigt die Shell, entfernt ihren Signalhandler und beendet sich erneut, um die Standardaktion des Betriebssystems (abnormales Beenden) auszulösen. Alternativ führt sie den Signalhandler des Skripts aus, wie mit Trap festgelegt, und fährt fort.

Antwort1

Erstens exit 130handelt es sich nicht um einen abnormalen Ausgang. Es handelt sich um einen normalen Ausgang mit dem Ausgangsstatus 130. Wie ausman 3 wait(POSIX):

   If  the  information  pointed  to  by  stat_loc was stored by a call to
   waitpid()  that  specified  the  WUNTRACED     and  WCONTINUED   flags,
   exactly one of the macros WIFEXITED(*stat_loc), WIFSIGNALED(*stat_loc),
   WIFSTOPPED(*stat_loc),  and WIFCONTINUED(*stat_loc)  shall evaluate  to
   a non-zero value.

WIFEXITEDprüft den normalen Ausgang und WIFSIGNALLEDdie Beendigung aufgrund eines nicht abgefangenen Signals. Da sich diese gegenseitig ausschließen, exit 130ist ein normal.

Dass der Beendigungsstatus 130 ist, wenn ein Prozess durch SIGINT beendet wird, liegt daran, dass Bash ihn außerhalb des Prozesses auf 130 setzt, weil es eine Beendigung aufgrund von SIGINT erkannt hat:Warum setzt Bash bei Strg-C oder Strg-Z $? (Beendigungsstatus) auf einen Wert ungleich Null?

Zweitens sollte ein Prozess, der SIGINT verarbeitet und dann beendet wird, sich selbst mit SIGINT beenden. Gregs Wiki (eine hervorragende Quelle für Shell-Sachen) hateine Anmerkung dazu:

Wenn Sie einen Handler für SIGINT einrichten (anstatt die EXIT-Trap zu verwenden), sollten Sie sich darüber im Klaren sein, dass ein Prozess, der als Reaktion auf SIGINT beendet wird,tötet sich selbst mit SIGINTanstatt einfach zu beenden, um Probleme für den Aufrufer zu vermeiden. Daher:

trap 'rm -f "$tempfile"; trap - INT; kill -INT $$' INT

Wenn Sie das jetzt exit 130in Folgendes geändert haben:

trap - INT
kill -INT $$

Sie würden das erwartete Verhalten sehen.

verwandte Informationen