
Ich gebe mir wirklich Mühe zu verstehen, was ich falsch mache und warum.
Ich habe ein launch.sh
Skript, 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.sh
fort. Warum?
Ich habe das folgende Verhalten erwartet (laut diesem BlogSignal & Bash) :
launch.sh
Die Shell A mit dem im Hintergrund laufenden Skript wird unterbrochen, Bash wartet, bis process.sh
es fertig ist. Da process.sh
aufgrund 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 130
handelt 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.
WIFEXITED
prüft den normalen Ausgang und WIFSIGNALLED
die Beendigung aufgrund eines nicht abgefangenen Signals. Da sich diese gegenseitig ausschließen, exit 130
ist 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 130
in Folgendes geändert haben:
trap - INT
kill -INT $$
Sie würden das erwartete Verhalten sehen.