Ich habe ein Bash-Skript, das einen lang laufenden Prozess im Vordergrund läuft. Wenn es ein SIGQUIT-Signal empfängt, sollte es verschiedene Säuberungsvorgänge ausführen, wie das Töten von sich selbst und alle seine Kindprozesse (über das Löschen der Prozessgruppe usw.). Eine minimale Skript, welches das Signal fangen sollte, wird weiter unten (test_trap.sh
genannt):Wie Trap zuverlässig mit Bash im Vordergrund Vordergrund Kind Prozesse verwenden
#!/bin/bash
trap 'echo "TRAP CAUGHT"; exit 1' QUIT # other required signals are omitted for brevity
echo starting sleep
sleep 11666
echo ending sleep
echo done
Ich möchte das SIGHUP Signal an den Prozess des test_trap.sh
Skript senden. Das Senden eines SIGHUP an die test_trap.sh
löst jedoch nicht den Trap-Ausdruck aus, sondern nur, wenn ich das Signal an das Kind sleep 11666
Prozess sendet, feuert die Falle. Nachfolgend finden Sie eine Sitzung bash dies demonstrieren:
bash-4.1$ test_trap.sh &
[1] 19633
bash-4.1$ starting sleep
bash-4.1$ kill -s SIGQUIT 19633
bash-4.1$ jobs
[1]+ Running test_trap.sh &
bash-4.1$ ps -ef --forest --cols=10000 | grep '11666\|test_trap.sh' | grep -v grep
theuser 19633 12227 0 07:40 pts/4 00:00:00 \_ /bin/bash ./test_trap.sh
theuser 19634 19633 0 07:40 pts/4 00:00:00 | \_ sleep 11666
bash-4.1$ kill -s SIGQUIT 19634
bash-4.1$ Quit (core dumped)
TRAP CAUGHT
[1]+ Exit 1 test_trap.sh
bash-4.1$ ps -ef --forest --cols=10000 | grep '11666\|test_trap.sh' | grep -v grep
bash-4.1$
Beachten Sie, dass die „Schlaf 11666“ ist nur ein repräsentatives Verfahren. Dieser Prozess kann tatsächlich eine interaktive Subshell sein (z. B. bash -i
).
Warum fängt der Elternprozess test_trap.sh
nicht das SIGHUP-Signal ab? Warum sollte die Falle nur ausgelöst werden, wenn der Prozess für sleep 11666
gemeldet wurde?
Ich möchte nicht unkalkulierbare SIGKILL verwenden, da ich eine Auswahl von Bereinigungsoperationen im Trap-Ausdruck vornehmen muss.
Dieses Skript soll auf einer relativ aktuellen Version einer Linux-Distribution ausgeführt werden, die Bash enthält (z. B. nicht Cygwin).
Referenzen:
Ich muss dies als die Antwort markieren, da Sie meine Frage gestellt haben und es war sehr hilfreich. Ich sagte jedoch: "Dieser Prozess kann tatsächlich eine interaktive Subshell sein (z. B. bash -i)." Und ich hätte hinzufügen sollen: "Ich möchte den repräsentativen Prozess nicht in den Hintergrund stellen, weil er eine interaktive Shell sein könnte". – bgoodr
Beachten Sie, dass der Benutzer der interaktiven Subshell trotzdem eigene Traps einrichten kann, um zu vermeiden, dass die Shell vom Aufrufer unterbrochen wird. – chepner
@bgoodr haben Sie jemals eine Lösung gefunden, die den Prozess nicht in den Hintergrund stellt? – trex005