Beenden von Unterprozessen, nachdem das Skript beendet wurde oder beendet wurde

Beenden von Unterprozessen, nachdem das Skript beendet wurde oder beendet wurde

Angenommen, ich habe ein Skript wie das folgende

#!/usr/bin/env zsh
./subscript.sh &
# do stuff
...
# do more stuff

Ich möchte, dass der laufende Prozess subscript.sh(und alle von ihm initiierten Prozesse) immer dann vollständig beendet werden, wenn:

  1. Das obige Skript wird beendet
  2. Das obige Skript wird aus irgendeinem Grund beendet.

Wie kann ich das oben genannte durchsetzen? Wird dies automatisch von der Shell übernommen?

Antwort1

Die Shell wird ihre Unterprozesse definitiv nicht spontan beenden – schließlich soll ein Hintergrundjob im Hintergrund laufen und sich nicht um das Leben seines übergeordneten Prozesses kümmern. (Eine interaktive Shell wird unter Umständen ihre Unterprozesse beenden, wenn sie beendet wird – was nicht immer wünschenswert ist, dahernohup.)

Sie können das Shell-Skript so einstellen, dass es seine Hintergrundjobs beendet, wenn es beendet wird oder durch ein abfangbares Signal beendet wird. Notieren Sie die Prozess-IDs der Jobs und beenden Sie sie über eine Trap. Beachten Sie, dass dadurch nur die Jobs beendet werden (also der ursprüngliche Prozess, der im Hintergrund gestartet wurde), nicht aber deren Unterprozesse.

jobs=()
trap '((#jobs == 0)) || kill $jobs' EXIT HUP TERM INT
subscript1 & jobs+=($!)
subscript2 & jobs+=($!)

Wenn Sie sicher sein möchten, dass alle Prozesse und ihre Unterprozesse beendet werden, ist mehr Planung erforderlich. Eine Methode besteht darin, dafür zu sorgen, dass alle Prozesse eine eindeutige Datei geöffnet haben. Um sie alle zu beenden, beenden Sie alle Prozesse, die diese Datei geöffnet haben. Ein Unterprozess kann entkommen, indem er die Datei schließt.

#!/bin/sh
lock_file=$(mktemp)
exec 3<"$lock_file"
your_script
status=$?
exec 3<&-
fuser -k "$lock_file"
exit $status

Antwort2

Sie könnten EXIT abfangen und ein Signal an die Prozessgruppe des Skripts senden.

unter Linux

trap 'kill -SIGTERM 0' EXIT

unter FreeBSD

trap 'kill -15 -$$' EXIT

SIGKILList das einzige Signal, bei dem dies nicht funktionieren würde, da das Skript bedingungslos beendet wird.

verwandte Informationen