Zombies sollten jedoch verschwinden, wenn der Systemschnitter läuft. Ich gebe zu, dass ich Systeme gesehen habe, in denen Zombies verweilen, aber das ist untypisch.
Brian Knoblauch
7
Manchmal sind diese verweilenden Zombies für eine beängstigende Aktivität verantwortlich.
User1
Verwenden Sie einen der Befehle chronosoder herodes.
@ MichaelLeBarbierGrünewald Könnten Sie bitte auf diese Programme verlinken?
Styropor fliegen
Antworten:
305
Sie sagen nicht, ob der Baum, den Sie töten möchten, eine einzelne Prozessgruppe ist. (Dies ist häufig der Fall, wenn der Baum das Ergebnis eines Forkings von einem Serverstart oder einer Shell-Befehlszeile ist.) Sie können Prozessgruppen mithilfe von GNU ps wie folgt ermitteln:
ps x -o "%p %r %y %x %c "
Wenn es sich um eine Prozessgruppe handelt, die Sie beenden möchten, verwenden Sie einfach den kill(1)Befehl. Geben Sie jedoch anstelle einer Prozessnummer die Negation der Gruppennummer an. Verwenden Sie beispielsweise, um jeden Prozess in Gruppe 5112 abzubrechen kill -TERM -- -5112.
kill -74313 -bash: kill: 74313: ungültige Signalspezifikation Wenn ich die kill -15 -GPID hinzufüge, hat es perfekt funktioniert.
Adam Peck
51
Wie bei fast jedem Befehl üblich, sollten Sie ein normales Argument, das mit einem - beginnt und nicht als Schalter interpretiert werden soll, mit -: kill - -GPID
ysth
9
pgrepkann eine einfachere Möglichkeit bieten, die Prozessgruppen-ID zu finden. Führen Sie beispielsweise aus, um die Prozessgruppe von my-script.sh zu beenden kill -TERM -$(pgrep -o my-script.sh).
Josh Kelley
9
Schauen Sie sich besser stackoverflow.com/questions/392022/ an. Es ist eine weitaus elegantere Lösung. Wenn Sie die Pids der Kinder auflisten müssen, verwenden Sie:ps -o pid --no-headers --ppid $PARENT_PID
Szymon Jeż
4
Und wenn Sie das Format leicht ändern und sortieren, sehen Sie alle Prozesse schön gruppiert und beginnen mit (möglicherweise) dem übergeordneten Gruppenmitglied in jeder Gruppe:ps x -o "%r %p %y %x %c" | sort -nk1,2
haridsv
199
Beenden Sie alle Prozesse, die zum selben Prozessbaum gehören, mit der Prozessgruppen-ID ( PGID)
Besonderer Dank geht an Tanager und Speakus für Beiträge zu $PIDverbleibenden Speicherplätzen und OSX-Kompatibilität.
Erläuterung
kill -9 -"$PGID"=> Signal 9 ( KILL) an alle Kinder und Enkel senden ...
PGID=$(ps opgid= "$PID")=> Ruft die Prozessgruppen-ID von einer beliebigen Prozess-ID des Baums ab, nicht nur von der Prozess-Eltern-ID . Eine Variation von ps opgid= $PIDist, ps -o pgid --no-headers $PIDwo pgiddurch ersetzt werden kann pgrp. Aber:
psFügt führende Leerzeichen ein, wenn sie PIDweniger als fünf Stellen haben und rechts ausgerichtet sind, wie vom Tanager bemerkt . Sie können verwenden: PGID=$(ps opgid= "$PID" | tr -d ' ')
psVon OSX aus drucken Sie immer den Header, daher schlägt Speakus vor: PGID="$( ps -o pgid "$PID" | grep [0-9] | tr -d ' ' )"
grep -o [0-9]* druckt nur aufeinanderfolgende Ziffern (druckt keine Leerzeichen oder alphabetischen Überschriften).
Weitere Kommandozeilen
PGID=$(ps -o pgid= $PID | grep -o [0-9]*)
kill -TERM -"$PGID"# kill -15
kill -INT -"$PGID"# correspond to [CRTL+C] from keyboard
kill -QUIT -"$PGID"# correspond to [CRTL+\] from keyboard
kill -CONT -"$PGID"# restart a stopped process (above signals do not kill it)
sleep 2# wait terminate process (more time if required)
kill -KILL -"$PGID"# kill -9 if it does not intercept signals (or buggy)
Verjährung
Wie von David und Hubert Kario bemerkt , wenn er killvon einem Prozess aufgerufen wird, der zum selben Baum gehört,kill Gefahr, dass sie sich selbst töten bevor die gesamte beendet wird.
Stellen Sie daher sicher, dass Sie den Befehl mit einem Prozess ausführen, der eine andere Prozessgruppen-ID hat .
Führen Sie den Prozessbaum im Hintergrund mit '&' aus.
>./run-many-processes.sh &ProcessID=28957 begins (./run-many-processes.sh)ProcessID=28959 begins (./child.sh)ProcessID=28958 begins (./child.sh)ProcessID=28960 begins (./grandchild.sh)ProcessID=28961 begins (./grandchild.sh)ProcessID=28962 begins (./grandchild.sh)ProcessID=28963 begins (./grandchild.sh)> PID=$!# get the Parent Process ID> PGID=$(ps opgid="$PID")# get the Process Group ID> ps fj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
28348283492834928349 pts/328969Ss330210:00-bash
28349289572895728349 pts/328969 S 330210:00 \_ /bin/sh ./run-many-processes.sh
28957289582895728349 pts/328969 S 330210:00| \_ /bin/sh ./child.sh background
28958289612895728349 pts/328969 S 330210:00|| \_ /bin/sh ./grandchild.sh background
28961289652895728349 pts/328969 S 330210:00||| \_ sleep 999928958289632895728349 pts/328969 S 330210:00|| \_ /bin/sh ./grandchild.sh foreground
28963289672895728349 pts/328969 S 330210:00|| \_ sleep 999928957289592895728349 pts/328969 S 330210:00| \_ /bin/sh ./child.sh foreground
28959289602895728349 pts/328969 S 330210:00| \_ /bin/sh ./grandchild.sh background
28960289642895728349 pts/328969 S 330210:00|| \_ sleep 999928959289622895728349 pts/328969 S 330210:00| \_ /bin/sh ./grandchild.sh foreground
28962289662895728349 pts/328969 S 330210:00| \_ sleep 999928349289692896928349 pts/328969 R+330210:00 \_ ps fj
Der Befehl pkill -P $PIDtötet das Enkelkind nicht:
> pkill -P "$PID"./run-many-processes.sh: line 4:28958Terminated./child.sh background
./run-many-processes.sh: line 4:28959Terminated./child.sh foreground
ProcessID=28957 ends (./run-many-processes.sh)[1]+Done./run-many-processes.sh
> ps fj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
28348283492834928349 pts/328987Ss330210:00-bash
28349289872898728349 pts/328987 R+330210:00 \_ ps fj
1289632895728349 pts/328987 S 330210:00/bin/sh ./grandchild.sh foreground
28963289672895728349 pts/328987 S 330210:00 \_ sleep 99991289622895728349 pts/328987 S 330210:00/bin/sh ./grandchild.sh foreground
28962289662895728349 pts/328987 S 330210:00 \_ sleep 99991289612895728349 pts/328987 S 330210:00/bin/sh ./grandchild.sh background
28961289652895728349 pts/328987 S 330210:00 \_ sleep 99991289602895728349 pts/328987 S 330210:00/bin/sh ./grandchild.sh background
28960289642895728349 pts/328987 S 330210:00 \_ sleep 9999
Der Befehl beendet kill -- -$PGIDalle Prozesse einschließlich des Enkels.
> kill ---"$PGID"# default signal is TERM (kill -15)> kill -CONT -"$PGID"# awake stopped processes> kill -KILL -"$PGID"# kill -9 to be sure> ps fj
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
28348283492834928349 pts/329039Ss330210:00-bash
28349290392903928349 pts/329039 R+330210:00 \_ ps fj
Fazit
Ich bemerke in diesem Beispiel PIDund bin PGIDgleich ( 28957).
Deshalb dachte ich ursprünglich, es kill -- -$PIDsei genug. Für den Fall, dass der Prozess innerhalb einer erzeugt wird, unterscheidet sich Makefiledie Prozess-ID von der Gruppen-ID .
Ich denke, es kill -- -$(ps -o pgid= $PID | grep -o [0-9]*)ist der beste einfache Trick, einen ganzen Prozessbaum zu töten, wenn er von einer anderen Gruppen-ID (einem anderen Prozessbaum) aufgerufen wird .
Hallo @davide. Gute Frage. Ich denke, ich killsollte das Signal immer an den gesamten Baum senden, bevor ich ein eigenes Signal empfange. Unter bestimmten Umständen / Implementierungen killkann das Signal jedoch an sich selbst gesendet, unterbrochen und dann ein eigenes Signal empfangen werden. Das Risiko sollte jedoch minimal genug sein und kann in den meisten Fällen ignoriert werden, da andere Fehler vor diesem auftreten sollten. Kann dieses Risiko in Ihrem Fall ignoriert werden? Darüber hinaus haben andere Antworten diesen häufigen Fehler (ein killTeil des Prozessbaums wird getötet). Hoffe diese Hilfe .. Prost;)
Olibre
3
Dies funktioniert nur, wenn die Unterbefehle selbst keine Gruppenleiter werden. Sogar solche einfachen Werkzeuge mantun das. Auf der anderen Seite funktioniert kill -- -$pides nicht , wenn Sie den gandchild-Prozess aus dem untergeordneten Prozess beenden möchten . Es ist also keine generische Lösung.
Hubert Kario
1
Das Beispiel ist das "Kind", das versucht, seine Kinder zu töten (also Enkelkinder des vom Benutzer initiierten Befehls). IOW, versuchen Sie, die Hintergrundprozesshierarchie in zu beenden child.sh.
Hubert Kario
1
> kill -QUIT - "$ PGID" # dasselbe Signal wie [CRTL + C] von der Tastatur ---- QUIT sollte durch INT ersetzt werden, um wahr zu sein
Maxim Kholyavkin
1
für die OSX-Option --no-headers wird nicht unterstützt, daher sollte der Code aktualisiert werden auf: PGID = "$ (ps -o pgid" $ PID "| grep [0-9] | tr -d '')"
Maxim Kholyavkin
166
pkill -TERM -P 27888
Dadurch werden alle Prozesse beendet, die die übergeordnete Prozess-ID 27888 haben.
In meinem Schnelltest hat pgrep nur die unmittelbaren Kinder gemeldet, sodass möglicherweise nicht die gesamte Hierarchie zerstört wird.
Haridsv
10
Ich stimme @haridsv zu: pkill -Psendet das Signal nur an das Kind => das Enkelkind empfängt das Signal nicht => Deshalb habe ich eine andere Antwort geschrieben , um das zu erklären. Prost ;-)
Olibre
1
Verwenden Sie ein Bash-Skript, um Ihre eigenen Kinder zu töten pkill -TERM -P ${$}.
François Beausoleil
3
@Onlyjob, ist es nicht gefährlich zu schlafen und dann zu töten? Die Prozess-IDs wurden möglicherweise in der Zwischenzeit vom Betriebssystem wiederverwendet: Möglicherweise beenden Sie Prozesse, die nicht mehr Ihre Kinder sind. Ich vermute, dass der Aufruf von pkill erneut erfolgen müsste, um dies zu verhindern.
François Beausoleil
2
@Onlyjob FYI, ich bin in der Lage, 32768 Prozesse, Single-Threaded, mit leichtem E / A-Zugriff in weniger als 19 Sekunden auf meinem Computer zu $ time for i in {1..32768}; do ( echo $BASHPID >> pids ); done real 0m18.860s
erzeugen
102
Verwenden Sie killtree (), um einen Prozessbaum rekursiv zu beenden:
#!/bin/bash
killtree(){local _pid=$1
local _sig=${2:--TERM}
kill -stop ${_pid}# needed to stop quickly forking parent from producing children between child killing and parent killingfor _child in $(ps -o pid --no-headers --ppid ${_pid});do
killtree ${_child} ${_sig}done
kill -${_sig} ${_pid}}if[ $# -eq 0 -o $# -gt 2 ]; then
echo "Usage: $(basename $0) <pid> [signal]"
exit 1fi
killtree $@
Die --Argumente, psum unter OS X nicht zu funktionieren. Damit es dort funktioniert, ersetzen Sie den psBefehl durch: ps ax -o "pid= ppid=" | grep -E "${_regex}" | sed -E "s/${_regex}/\1/gwo _regexvor der forSchleife definiert ist :local _regex="[ ]*([0-9]+)[ ]+${_pid}"
artur
5
Gestoppte Prozesse werden mit SIGTERM nicht beendet. Siehe meine Antwort
x-yuri
1
-1 verwendet #! / Bin / bash anstelle von #! / Usr / bin / env bash (oder besser noch POSIX nur Konstrukte und / bin / sh)
Gute Person
Würde es ausreichen, anstelle von SIGTERM ein SIGKILL zu senden, um sicherzustellen, dass dies killtree()zuverlässig funktioniert?
David
3
Wenn psnicht unterstützt --ppid, kann man pgrep -P ${_pid}stattdessen verwenden
Hubert Kario
16
Der Befehl rkill aus dem pslist- Paket sendet ein bestimmtes Signal (oderSIGTERMstandardmäßig) an den angegebenen Prozess und alle seine Nachkommen:
Einige Versionen von ps geben eine Warnung aus, wenn Sie "-ax" anstelle von "ax" verwenden. Also: für Kind in $ (ps -o pid, ppid ax | \ awk "{if (\ $ 2 == $ pid) {print \ $ 1}}")
Vereinfachen mit grep, anstatt sed ...pstree -p 24901 | grep -oP '(?<=\()[0-9]+(?=\))'
anishsane
2
Sie sollte noch hinzufügen -lzu pstree, so lange Linien erhalten abgeschnitten nicht; es kann einfacher gemacht werden, auch mit zu lesen kill `pstree -l -p 24901 |grep "([[:digit:]]*)" -o |tr -d '()'`(keine Notwendigkeit, \nin den Raum zu konvertieren , da es gut funktioniert), danke!
Wassermann Power
9
Geänderte Version von Zhigangs Antwort:
#!/usr/bin/env bashset-eu
killtree(){local pid
for pid;do
kill -stop $pid
local cpid
for cpid in $(pgrep -P $pid);do
killtree $cpid
done
kill $pid
kill -cont $pid
wait $pid 2>/dev/null || true
done}
cpids(){local pid=$1 options=${2:-} space=${3:-}local cpid
for cpid in $(pgrep -P $pid);do
echo "$space$cpid"if[["${options/a/}"!="$options"]];then
cpids $cpid "$options""$space "fidone}while true;do sleep 1;done&
cpid=$!for i in $(seq 12);do
cpids $$ a
sleep 1done
killtree $cpid
echo ---
cpids $$ a
Sie können wait $pidnur auf Prozesse, die Sie gestartet haben, nicht alle Prozesse, so dass dies keine generische Lösung ist
Hubert Kario
@ Hubert Kario In diesem Fall wird wait nur mit einem Status ungleich Null beendet und das Skript weiter ausgeführt. Liege ich falsch? Aber waitwird unterdrücken TerminatedNachricht , wenn es ein Kind ist.
X-Yuri
9
Ich kann nicht kommentieren (nicht genug Ruf), daher bin ich gezwungen, eine neue Antwort hinzuzufügen , obwohl dies nicht wirklich eine Antwort ist.
Es gibt ein kleines Problem mit der ansonsten sehr schönen und gründlichen Antwort von @olibre am 28. Februar. Die Ausgabe von ps opgid= $PIDenthält führende Leerzeichen für eine PID mit weniger als fünf Ziffern, da dies psdie Spalte rechtfertigt (die Zahlen genau ausrichten). Innerhalb der gesamten Befehlszeile führt dies zu einem negativen Vorzeichen, gefolgt von Leerzeichen, gefolgt von der Gruppen-PID. Einfache Lösung ist mit dem Rohr pszu trzu entfernen Plätzen:
Die Funktion setsid () erstellt eine neue Sitzung, wenn der aufrufende Prozess kein Prozessgruppenleiter ist. Bei der Rückkehr ist der aufrufende Prozess der Sitzungsleiter dieser neuen Sitzung, der Prozessgruppenleiter einer neuen Prozessgruppe und hat kein kontrollierendes Terminal. Die Prozessgruppen-ID des aufrufenden Prozesses wird gleich der Prozess-ID des aufrufenden Prozesses gesetzt. Der aufrufende Prozess ist der einzige Prozess in der neuen Prozessgruppe und der einzige Prozess in der neuen Sitzung.
Was ich damit meine, dass Sie vom Startvorgang an eine Gruppe erstellen können. Ich habe dies in PHP verwendet, um einen ganzen Prozessbaum nach dem Start töten zu können.
Dies kann eine schlechte Idee sein. Ich würde mich für Kommentare interessieren.
Eigentlich ist das eine tolle Idee und funktioniert sehr gut. Ich verwende es in Fällen, in denen ich Prozesse in dieselbe Prozessgruppe einordnen kann (oder sie sind bereits in derselben Gruppe).
Anstatt ihm eine Prozessnummer zu geben, geben Sie ihm die Negation der Gruppennummer. Wie bei fast jedem Befehl üblich, sollten Sie ein normales Argument, das mit a beginnt -und nicht als Schalter interpretiert werden soll, voranstellen--
Hoppla, ich habe gerade festgestellt, dass ich die gleiche Antwort wie Sie gegeben habe => +1. Aber darüber hinaus erkläre ich , wie einfach zu bekommen PGIDaus PID. Was denken Sie? Cheers
Olibre
5
Die folgende Shell-Funktion ähnelt vielen anderen Antworten, funktioniert jedoch sowohl unter Linux als auch unter BSD (OS X usw.) ohne externe Abhängigkeiten wie pgrep:
killtree(){local parent=$1 child
for child in $(ps -o ppid=-o pid=| awk "\$1==$parent {print \$2}");do
killtree $child
done
kill $parent
}
Ich denke, Sie haben ein zusätzliches Wort "Kind" am Ende der 2. Zeile.
Mato
@mato - Das ist kein Extra. Es beschränkt den Umfang $childdieser Funktion, um andere (nicht lokale) Variablen mit demselben Namen nicht zu stören und um sicherzustellen, dass der Wert der lokalen Variablen nach Beendigung der Funktion bereinigt wird.
Adam Katz
Oh, ich verstehe jetzt, ich dachte, es wäre Teil der Aufgabe. Ich denke, ich sollte noch einmal lesen (langsamer), bevor ich einen Kommentar schreibe. :) Vielen Dank.
Mato
Übrigens, wäre es nicht besser, eine Liste von Kindern zu erstellen und dann von oben (Eltern) zu töten? Auf diese Weise können wir eine Situation vermeiden, in der ein Elternteil ein Kind neu erstellt oder den nächsten Code weiter ausführt, wodurch möglicherweise das beabsichtigte Verhalten geändert wird.
Mato
5
Mit Python mit Psutil ist das ganz einfach . Installieren Sie einfach psutil mit pip und Sie haben eine vollständige Suite von Prozessmanipulations-Tools:
def killChildren(pid):
parent = psutil.Process(pid)for child in parent.get_children(True):if child.is_running():
child.terminate()
Es scheint sowohl auf Macs als auch auf Linux gut zu funktionieren. In Situationen, in denen Sie sich nicht darauf verlassen können, Prozessgruppen verwalten zu können - beispielsweise beim Schreiben von Skripten zum Testen einer Software, die in mehreren Umgebungen erstellt werden muss - ist diese Tree-Walking-Technik auf jeden Fall hilfreich.
Danke für deine Weisheit, Leute. Mein Skript hinterließ beim Beenden einige untergeordnete Prozesse, und der Negationstipp erleichterte die Arbeit. Ich habe diese Funktion geschrieben, um sie bei Bedarf in anderen Skripten zu verwenden:
# kill my group's subprocesses: killGroup# kill also myself: killGroup -x# kill another group's subprocesses: killGroup N # kill that group all: killGroup -x N# N: PID of the main process (= process group ID).function killGroup (){local prid mainpid
case $1 in-x)[-n "$2"]&& kill -9-$2 || kill -9-$$ ;;"") mainpid=$$ ;;*) mainpid=$1 ;;esac
prid=$(ps ax -o pid,pgid | grep $mainpid)
prid=${prid//$mainpid/}
kill -9 $prid 2>/dev/null
return}
Es ist wahrscheinlich besser, die Eltern vor den Kindern zu töten; Andernfalls kann der Elternteil wahrscheinlich wieder neue Kinder hervorbringen, bevor er selbst getötet wird. Diese werden das Töten überleben.
Meine Version von ps unterscheidet sich von der oben genannten; vielleicht zu alt, deshalb das seltsame grepping ...
Die Verwendung eines Shell-Skripts anstelle einer Shell-Funktion hat viele Vorteile ...
Beachten Sie, dass das @ zhighang-Skript den übergeordneten Prozess SIGSTOPT und ein Signal an den gestoppten Prozess liefert. Dies sollte also nicht (AFAIK) zu einer Race-Bedingung zwischen dem Erstellen von untergeordneten Prozessen und der Signalübermittlung führen. Ihre Version hat jedoch einen Wettlauf zwischen dem Abrufen der Liste der Kinder und der Signalübermittlung an die Eltern.
Hubert Kario
1
Das Folgende wurde unter FreeBSD, Linux und MacOS X getestet und hängt nur von pgrep und kill ab (die ps-o-Versionen funktionieren nicht unter BSD). Das erste Argument ist die Eltern-PID, deren Kinder beendet werden müssen. Das zweite Argument ist ein Boolescher Wert, um zu bestimmen, ob die übergeordnete PID ebenfalls beendet werden muss.
Dadurch wird SIGTERM an einen untergeordneten Prozess innerhalb eines Shell-Skripts gesendet. Wenn SIGTERM nicht erfolgreich ist, wartet es 10 Sekunden und sendet dann kill.
Frühere Antwort:
Das Folgende funktioniert auch, wird aber die Shell selbst auf BSD töten.
KillSubTree(){local parent="${1}"for child in $(ps -o pid=$parent);doif[ $$ -ne $child ];then(kill -s SIGTERM $child ||(sleep 10&& kill -9 $child &))>/dev/null 2>&1;fidone}# Example lanch from within scriptKillSubTree $$ >/dev/null 2>&1
Ich entwickle die Lösung von Zhigang, Xyuri und Solidsneck weiter:
#!/bin/bashif test $# -lt 1 ; then
echo >&2"usage: kiltree pid (sig)"
exit 1;fi;
_pid=$1
_sig=${2:-TERM}# echo >&2 "killtree($_pid) mypid = $$"# ps axwwf | grep -6 "^[ ]*$_pid " >&2 ;function _killtree (){local _children
local _child
local _success
if test $1 -eq $2 ;then# this is killtree - don't commit suicide!
echo >&2"killtree can´t kill it´s own branch - some processes will survive.";return1;fi;# this avoids that children are spawned or disappear.
kill -SIGSTOP $2 ;
_children=$(ps -o pid --no-headers --ppid $2);
_success=0for _child in ${_children};do
_killtree $1 ${_child} $3 ;
_success=$(($_success+$?));done;if test $_success -eq 0;then
kill -$3 $2
fi;# when a stopped process is killed, it will linger in the system until it is continued
kill -SIGCONT $2
test $_success -eq 0;return $?}
_killtree $$ $_pid $_sig
Diese Version vermeidet das Töten ihrer Vorfahren - was in den vorherigen Lösungen zu einer Flut von untergeordneten Prozessen führt.
Prozesse werden ordnungsgemäß gestoppt, bevor die untergeordnete Liste festgelegt wird, sodass keine neuen untergeordneten Elemente erstellt werden oder verschwinden.
Nach dem Tod müssen die gestoppten Jobs weiterhin aus dem System verschwinden.
Alte Frage, ich weiß, aber alle Antworten scheinen weiterhin ps zu nennen, was mir nicht gefallen hat.
Diese awk-basierte Lösung erfordert keine Rekursion und ruft ps nur einmal auf.
awk 'BEGIN {
p=1390
while ("ps -o ppid,pid"|getline) a[$1]=a[$1]" "$2
o=1
while (o==1) {
o=0
split(p, q, " ")
for (i in q) if (a[q[i]]!="") {
p=p""a[q[i]]
o=1
a[q[i]]=""
}
}
system("kill -TERM "p)
}'
Oder in einer Zeile:
awk 'BEGIN {p=1390;while ("ps -o ppid,pid"|getline) a[$1]=a[$1]" "$2;o=1;while (o==1) {o=0;split(p, q, " ");for (i in q) {if (a[q[i]]!="") {p=p""a[q[i]];o=1;a[q[i]]=""}}}system("kill -TERM "p)}'
Grundsätzlich besteht die Idee darin, ein Array (a) von Parent: Child-Einträgen aufzubauen und dann das Array zu durchlaufen, um Kinder für unsere übereinstimmenden Eltern zu finden, und sie im Laufe der Zeit zu unserer Elternliste (p) hinzuzufügen.
Wenn Sie den Prozess der obersten Ebene nicht beenden möchten, tun Sie dies
sub(/[0-9]*/,"", p)
kurz bevor die system () - Zeile sie aus dem Kill-Set entfernen würde.
Denken Sie daran, dass es hier eine Rennbedingung gibt, aber das gilt (soweit ich sehen kann) für alle Lösungen. Es macht das, was ich brauchte, weil das Skript, für das ich es brauchte, nicht viele kurzlebige Kinder schafft.
Eine Übung für den Leser wäre, es zu einer 2-Pass-Schleife zu machen: Senden Sie nach dem ersten Durchgang SIGSTOP an alle Prozesse in der p-Liste, dann eine Schleife, um ps erneut auszuführen, und senden Sie nach dem zweiten Durchgang SIGTERM und dann SIGCONT. Wenn Sie sich nicht für schöne Enden interessieren, könnte der zweite Durchgang einfach SIGKILL sein, nehme ich an.
Wenn Sie die PID der Sache kennen, die Sie töten möchten, können Sie normalerweise von der Sitzungs-ID und von allem in derselben Sitzung ausgehen. Ich würde es noch einmal überprüfen, aber ich habe dies für Skripte verwendet, die rsyncs in Schleifen starten, die ich sterben möchte, und keine andere (wegen der Schleife) starten, als würde ich nur rsync töten.
In sh listet der Befehl jobs die Hintergrundprozesse auf. In einigen Fällen ist es möglicherweise besser, zuerst den neuesten Prozess abzubrechen, z. B. hat der ältere einen gemeinsam genutzten Socket erstellt. In diesen Fällen sortieren Sie die PIDs in umgekehrter Reihenfolge. Manchmal möchten Sie einen Moment warten, bis die Jobs etwas auf die Festplatte oder ähnliches geschrieben haben, bevor sie beendet werden.
Und töte nicht, wenn du nicht musst!
for SIGNAL in TERM KILL;dofor CHILD in $(jobs -s|sort -r);do
kill -s $SIGNAL $CHILD
sleep $MOMENT
donedone
Oft müssen wir untergeordnete Prozesse beenden, die aus irgendeinem Grund gehängt oder blockiert werden. z.B. Problem mit der FTP-Verbindung.
Es gibt zwei Ansätze:
1) Erstellen eines separaten neuen Elternteils für jedes Kind, das den untergeordneten Prozess überwacht und beendet, sobald das Zeitlimit erreicht ist.
und beobachten Sie Prozesse, die in einem anderen Terminal den Namen 'test' haben, mit dem folgenden Befehl.
watch -n1 'ps x -o "%p %r %c" | grep "test" '
Das obige Skript erstellt 4 neue untergeordnete Prozesse und deren Eltern. Jeder untergeordnete Prozess wird 10 Sekunden lang ausgeführt. Sobald jedoch eine Zeitüberschreitung von 5 Sekunden erreicht ist, werden diese Kinder durch ihre jeweiligen übergeordneten Prozesse getötet. Das Kind kann die Ausführung also nicht abschließen (10 Sekunden). Spielen Sie mit diesen Timings (Schalter 10 und 5), um ein anderes Verhalten zu sehen. In diesem Fall beendet das Kind die Ausführung in 5 Sekunden, bevor das Zeitlimit von 10 Sekunden erreicht ist.
2) Lassen Sie den aktuellen übergeordneten Prozess überwachen und beenden, sobald das Timeout erreicht ist. Dadurch wird kein separates übergeordnetes Element erstellt, um jedes untergeordnete Element zu überwachen. Außerdem können Sie alle untergeordneten Prozesse innerhalb desselben übergeordneten Prozesses ordnungsgemäß verwalten.
Erstellen Sie test.sh wie folgt:
#!/bin/bash
declare -A CPIDs;
declare -a CMDs=("AAA""BBB""CCC""DDD")
CMD_TIME=15;for CMD in ${CMDs[*]};do(echo "Started..$CMD"; sleep $CMD_TIME; echo "$CMD Done";)&CPIDs[$!]="$RN";
sleep 1;done
GPID=$(ps -o pgid= $$);
CNT_TIME_OUT=10;
CNT=0;while(true);do
declare -A TMP_CPIDs;for PID in"${!CPIDs[@]}";do
echo "Checking "${CPIDs[$PID]}"=>"$PID;if ps -p $PID >/dev/null ;then
echo "-->"${CPIDs[$PID]}"=>"$PID" is running..";
TMP_CPIDs[$PID]=${CPIDs[$PID]};else
echo "-->"${CPIDs[$PID]}"=>"$PID" is completed.";fidoneif[ ${#TMP_CPIDs[@]}==0];then
echo "All commands completed.";break;else
unset CPIDs;
declare -A CPIDs;for PID in"${!TMP_CPIDs[@]}";doCPIDs[$PID]=${TMP_CPIDs[$PID]};done
unset TMP_CPIDs;if[ $CNT -gt $CNT_TIME_OUT ];then
echo ${CPIDs[@]}"PIDs not reponding. Timeout reached $CNT sec. killing all childern with GPID $GPID..";
kill ---$GPID;fifi
CNT=$((CNT+1));
echo "waiting since $b secs..";
sleep 1;done
exit;
und beobachten Sie Prozesse, die in einem anderen Terminal den Namen 'test' haben, mit dem folgenden Befehl.
watch -n1 'ps x -o "%p %r %c" | grep "test" '
Das obige Skript erstellt 4 neue untergeordnete Prozesse. Wir speichern Pids aller untergeordneten Prozesse und durchlaufen sie, um zu überprüfen, ob sie ausgeführt wurden oder noch ausgeführt werden. Der untergeordnete Prozess wird bis zur CMD_TIME-Zeit ausgeführt. Wenn das Zeitlimit für CNT_TIME_OUT erreicht ist, werden alle Kinder vom übergeordneten Prozess getötet. Sie können das Timing wechseln und mit dem Skript herumspielen, um das Verhalten zu sehen. Ein Nachteil dieses Ansatzes besteht darin, dass die Gruppen-ID zum Töten aller untergeordneten Bäume verwendet wird. Der übergeordnete Prozess selbst gehört jedoch zur selben Gruppe, sodass er auch getötet wird.
Möglicherweise müssen Sie dem übergeordneten Prozess eine andere Gruppen-ID zuweisen, wenn Sie nicht möchten, dass das übergeordnete Element getötet wird.
#/bin/sh
while true
do
echo "Enter parent process id [type quit for exit]"
read ppid
if [ $ppid -eq "quit" -o $ppid -eq "QUIT" ];then
exit 0
fi
for i in `ps -ef| awk '$3 == '$ppid' { print $2 }'`
do
echo killing $i
kill $i
done
done
chronos
oderherodes
.Antworten:
Sie sagen nicht, ob der Baum, den Sie töten möchten, eine einzelne Prozessgruppe ist. (Dies ist häufig der Fall, wenn der Baum das Ergebnis eines Forkings von einem Serverstart oder einer Shell-Befehlszeile ist.) Sie können Prozessgruppen mithilfe von GNU ps wie folgt ermitteln:
Wenn es sich um eine Prozessgruppe handelt, die Sie beenden möchten, verwenden Sie einfach den
kill(1)
Befehl. Geben Sie jedoch anstelle einer Prozessnummer die Negation der Gruppennummer an. Verwenden Sie beispielsweise, um jeden Prozess in Gruppe 5112 abzubrechenkill -TERM -- -5112
.quelle
pgrep
kann eine einfachere Möglichkeit bieten, die Prozessgruppen-ID zu finden. Führen Sie beispielsweise aus, um die Prozessgruppe von my-script.sh zu beendenkill -TERM -$(pgrep -o my-script.sh)
.ps -o pid --no-headers --ppid $PARENT_PID
ps x -o "%r %p %y %x %c" | sort -nk1,2
Beenden Sie alle Prozesse, die zum selben Prozessbaum gehören, mit der Prozessgruppen-ID (
PGID
)kill -- -$PGID
Standard-Signal verwenden (TERM
= 15)kill -9 -$PGID
Verwende das SignalKILL
(9)Sie können die
PGID
von jeder Prozess-ID (PID
) desselben Prozessbaums abrufenkill -- -$(ps -o pgid= $PID | grep -o '[0-9]*')
(SignalTERM
)kill -9 -$(ps -o pgid= $PID | grep -o '[0-9]*')
(SignalKILL
)Besonderer Dank geht an Tanager und Speakus für Beiträge zu
$PID
verbleibenden Speicherplätzen und OSX-Kompatibilität.Erläuterung
kill -9 -"$PGID"
=> Signal 9 (KILL
) an alle Kinder und Enkel senden ...PGID=$(ps opgid= "$PID")
=> Ruft die Prozessgruppen-ID von einer beliebigen Prozess-ID des Baums ab, nicht nur von der Prozess-Eltern-ID . Eine Variation vonps opgid= $PID
ist,ps -o pgid --no-headers $PID
wopgid
durch ersetzt werden kannpgrp
.Aber:
ps
Fügt führende Leerzeichen ein, wenn siePID
weniger als fünf Stellen haben und rechts ausgerichtet sind, wie vom Tanager bemerkt . Sie können verwenden:PGID=$(ps opgid= "$PID" | tr -d ' ')
ps
Von OSX aus drucken Sie immer den Header, daher schlägt Speakus vor:PGID="$( ps -o pgid "$PID" | grep [0-9] | tr -d ' ' )"
grep -o [0-9]*
druckt nur aufeinanderfolgende Ziffern (druckt keine Leerzeichen oder alphabetischen Überschriften).Weitere Kommandozeilen
Verjährung
kill
von einem Prozess aufgerufen wird, der zum selben Baum gehört,kill
Gefahr, dass sie sich selbst töten bevor die gesamte beendet wird.Lange Geschichte
Führen Sie den Prozessbaum im Hintergrund mit '&' aus.
Der Befehl
pkill -P $PID
tötet das Enkelkind nicht:Der Befehl beendet
kill -- -$PGID
alle Prozesse einschließlich des Enkels.Fazit
Ich bemerke in diesem Beispiel
PID
und binPGID
gleich (28957
).Deshalb dachte ich ursprünglich, es
kill -- -$PID
sei genug. Für den Fall, dass der Prozess innerhalb einer erzeugt wird, unterscheidet sichMakefile
die Prozess-ID von der Gruppen-ID .Ich denke, es
kill -- -$(ps -o pgid= $PID | grep -o [0-9]*)
ist der beste einfache Trick, einen ganzen Prozessbaum zu töten, wenn er von einer anderen Gruppen-ID (einem anderen Prozessbaum) aufgerufen wird .quelle
kill
sollte das Signal immer an den gesamten Baum senden, bevor ich ein eigenes Signal empfange. Unter bestimmten Umständen / Implementierungenkill
kann das Signal jedoch an sich selbst gesendet, unterbrochen und dann ein eigenes Signal empfangen werden. Das Risiko sollte jedoch minimal genug sein und kann in den meisten Fällen ignoriert werden, da andere Fehler vor diesem auftreten sollten. Kann dieses Risiko in Ihrem Fall ignoriert werden? Darüber hinaus haben andere Antworten diesen häufigen Fehler (einkill
Teil des Prozessbaums wird getötet). Hoffe diese Hilfe .. Prost;)man
tun das. Auf der anderen Seite funktioniertkill -- -$pid
es nicht , wenn Sie den gandchild-Prozess aus dem untergeordneten Prozess beenden möchten . Es ist also keine generische Lösung.child.sh
.Dadurch werden alle Prozesse beendet, die die übergeordnete Prozess-ID 27888 haben.
Oder robuster:
welcher Zeitplan 33 Sekunden später tötet und die Prozesse höflich auffordert, zu beenden.
In dieser Antwort finden Sie Informationen zum Beenden aller Nachkommen.
quelle
pkill -P
sendet das Signal nur an das Kind => das Enkelkind empfängt das Signal nicht => Deshalb habe ich eine andere Antwort geschrieben , um das zu erklären. Prost ;-)pkill -TERM -P ${$}
.$ time for i in {1..32768}; do ( echo $BASHPID >> pids ); done real 0m18.860s
Verwenden Sie killtree (), um einen Prozessbaum rekursiv zu beenden:
quelle
--
Argumente,ps
um unter OS X nicht zu funktionieren. Damit es dort funktioniert, ersetzen Sie denps
Befehl durch:ps ax -o "pid= ppid=" | grep -E "${_regex}" | sed -E "s/${_regex}/\1/g
wo_regex
vor derfor
Schleife definiert ist :local _regex="[ ]*([0-9]+)[ ]+${_pid}"
killtree()
zuverlässig funktioniert?ps
nicht unterstützt--ppid
, kann manpgrep -P ${_pid}
stattdessen verwendenDer Befehl rkill aus dem pslist- Paket sendet ein bestimmtes Signal (oder
SIGTERM
standardmäßig) an den angegebenen Prozess und alle seine Nachkommen:quelle
Brads Antwort würde ich auch empfehlen, außer dass Sie sie
awk
ganz abschaffen können, wenn Sie die--ppid
Option dazu verwendenps
.quelle
Wenn Sie wissen, dass Sie die PID des übergeordneten Prozesses übergeben haben, finden Sie hier ein Shell-Skript, das funktionieren sollte:
quelle
Ich verwende eine etwas modifizierte Version einer hier beschriebenen Methode: https://stackoverflow.com/a/5311362/563175
So sieht es aus:
Dabei ist 24901 die PID des Elternteils.
Es sieht ziemlich hässlich aus, macht aber seinen Job perfekt.
quelle
pstree -p 24901 | grep -oP '(?<=\()[0-9]+(?=\))'
-l
zupstree
, so lange Linien erhalten abgeschnitten nicht; es kann einfacher gemacht werden, auch mit zu lesenkill `pstree -l -p 24901 |grep "([[:digit:]]*)" -o |tr -d '()'`
(keine Notwendigkeit,\n
in den Raum zu konvertieren , da es gut funktioniert), danke!Geänderte Version von Zhigangs Antwort:
quelle
wait $pid
nur auf Prozesse, die Sie gestartet haben, nicht alle Prozesse, so dass dies keine generische Lösung istwait
wird unterdrückenTerminated
Nachricht , wenn es ein Kind ist.Ich kann nicht kommentieren (nicht genug Ruf), daher bin ich gezwungen, eine neue Antwort hinzuzufügen , obwohl dies nicht wirklich eine Antwort ist.
Es gibt ein kleines Problem mit der ansonsten sehr schönen und gründlichen Antwort von @olibre am 28. Februar. Die Ausgabe von
ps opgid= $PID
enthält führende Leerzeichen für eine PID mit weniger als fünf Ziffern, da diesps
die Spalte rechtfertigt (die Zahlen genau ausrichten). Innerhalb der gesamten Befehlszeile führt dies zu einem negativen Vorzeichen, gefolgt von Leerzeichen, gefolgt von der Gruppen-PID. Einfache Lösung ist mit dem Rohrps
zutr
zu entfernen Plätzen:quelle
Um die Antwort von Norman Ramsey zu ergänzen, lohnt es sich möglicherweise, sich setsid anzusehen, wenn Sie eine Prozessgruppe erstellen möchten.
http://pubs.opengroup.org/onlinepubs/009695399/functions/setsid.html
Was ich damit meine, dass Sie vom Startvorgang an eine Gruppe erstellen können. Ich habe dies in PHP verwendet, um einen ganzen Prozessbaum nach dem Start töten zu können.
Dies kann eine schlechte Idee sein. Ich würde mich für Kommentare interessieren.
quelle
Inspiriert von Ysths Kommentar
quelle
PGID
ausPID
. Was denken Sie? CheersDie folgende Shell-Funktion ähnelt vielen anderen Antworten, funktioniert jedoch sowohl unter Linux als auch unter BSD (OS X usw.) ohne externe Abhängigkeiten wie
pgrep
:quelle
$child
dieser Funktion, um andere (nicht lokale) Variablen mit demselben Namen nicht zu stören und um sicherzustellen, dass der Wert der lokalen Variablen nach Beendigung der Funktion bereinigt wird.Mit Python mit Psutil ist das ganz einfach . Installieren Sie einfach psutil mit pip und Sie haben eine vollständige Suite von Prozessmanipulations-Tools:
quelle
Basierend auf Zhigangs Antwort vermeidet dies Selbsttötung:
quelle
Wenn Sie einen Prozess mit Namen beenden möchten:
oder
quelle
Dies ist meine Version des Beendens aller untergeordneten Prozesse mit dem Bash-Skript. Es verwendet keine Rekursion und hängt vom Befehl pgrep ab.
Verwenden
Inhalt von killtrees.sh
quelle
Hier ist eine Variation von @ zhigangs Antwort, die ohne AWK auskommt und sich nur auf Bashs native Parsing-Möglichkeiten stützt:
Es scheint sowohl auf Macs als auch auf Linux gut zu funktionieren. In Situationen, in denen Sie sich nicht darauf verlassen können, Prozessgruppen verwalten zu können - beispielsweise beim Schreiben von Skripten zum Testen einer Software, die in mehreren Umgebungen erstellt werden muss - ist diese Tree-Walking-Technik auf jeden Fall hilfreich.
quelle
Danke für deine Weisheit, Leute. Mein Skript hinterließ beim Beenden einige untergeordnete Prozesse, und der Negationstipp erleichterte die Arbeit. Ich habe diese Funktion geschrieben, um sie bei Bedarf in anderen Skripten zu verwenden:
Prost.
quelle
Wenn Sie pstree und perl auf Ihrem System haben, können Sie Folgendes versuchen:
quelle
Es ist wahrscheinlich besser, die Eltern vor den Kindern zu töten; Andernfalls kann der Elternteil wahrscheinlich wieder neue Kinder hervorbringen, bevor er selbst getötet wird. Diese werden das Töten überleben.
Meine Version von ps unterscheidet sich von der oben genannten; vielleicht zu alt, deshalb das seltsame grepping ...
Die Verwendung eines Shell-Skripts anstelle einer Shell-Funktion hat viele Vorteile ...
Es ist jedoch im Grunde Zhigangs Idee
quelle
Das Folgende wurde unter FreeBSD, Linux und MacOS X getestet und hängt nur von pgrep und kill ab (die ps-o-Versionen funktionieren nicht unter BSD). Das erste Argument ist die Eltern-PID, deren Kinder beendet werden müssen. Das zweite Argument ist ein Boolescher Wert, um zu bestimmen, ob die übergeordnete PID ebenfalls beendet werden muss.
Dadurch wird SIGTERM an einen untergeordneten Prozess innerhalb eines Shell-Skripts gesendet. Wenn SIGTERM nicht erfolgreich ist, wartet es 10 Sekunden und sendet dann kill.
Frühere Antwort:
Das Folgende funktioniert auch, wird aber die Shell selbst auf BSD töten.
quelle
Ich entwickle die Lösung von Zhigang, Xyuri und Solidsneck weiter:
Diese Version vermeidet das Töten ihrer Vorfahren - was in den vorherigen Lösungen zu einer Flut von untergeordneten Prozessen führt.
Prozesse werden ordnungsgemäß gestoppt, bevor die untergeordnete Liste festgelegt wird, sodass keine neuen untergeordneten Elemente erstellt werden oder verschwinden.
Nach dem Tod müssen die gestoppten Jobs weiterhin aus dem System verschwinden.
quelle
Alte Frage, ich weiß, aber alle Antworten scheinen weiterhin ps zu nennen, was mir nicht gefallen hat.
Diese awk-basierte Lösung erfordert keine Rekursion und ruft ps nur einmal auf.
Oder in einer Zeile:
Grundsätzlich besteht die Idee darin, ein Array (a) von Parent: Child-Einträgen aufzubauen und dann das Array zu durchlaufen, um Kinder für unsere übereinstimmenden Eltern zu finden, und sie im Laufe der Zeit zu unserer Elternliste (p) hinzuzufügen.
Wenn Sie den Prozess der obersten Ebene nicht beenden möchten, tun Sie dies
kurz bevor die system () - Zeile sie aus dem Kill-Set entfernen würde.
Denken Sie daran, dass es hier eine Rennbedingung gibt, aber das gilt (soweit ich sehen kann) für alle Lösungen. Es macht das, was ich brauchte, weil das Skript, für das ich es brauchte, nicht viele kurzlebige Kinder schafft.
Eine Übung für den Leser wäre, es zu einer 2-Pass-Schleife zu machen: Senden Sie nach dem ersten Durchgang SIGSTOP an alle Prozesse in der p-Liste, dann eine Schleife, um ps erneut auszuführen, und senden Sie nach dem zweiten Durchgang SIGTERM und dann SIGCONT. Wenn Sie sich nicht für schöne Enden interessieren, könnte der zweite Durchgang einfach SIGKILL sein, nehme ich an.
quelle
Wenn Sie die PID der Sache kennen, die Sie töten möchten, können Sie normalerweise von der Sitzungs-ID und von allem in derselben Sitzung ausgehen. Ich würde es noch einmal überprüfen, aber ich habe dies für Skripte verwendet, die rsyncs in Schleifen starten, die ich sterben möchte, und keine andere (wegen der Schleife) starten, als würde ich nur rsync töten.
Wenn Sie die PID nicht kennen, können Sie immer noch mehr nisten
quelle
quelle
kill -9
wirklich.kill -15
hilft es nicht.In sh listet der Befehl jobs die Hintergrundprozesse auf. In einigen Fällen ist es möglicherweise besser, zuerst den neuesten Prozess abzubrechen, z. B. hat der ältere einen gemeinsam genutzten Socket erstellt. In diesen Fällen sortieren Sie die PIDs in umgekehrter Reihenfolge. Manchmal möchten Sie einen Moment warten, bis die Jobs etwas auf die Festplatte oder ähnliches geschrieben haben, bevor sie beendet werden.
Und töte nicht, wenn du nicht musst!
quelle
Untergeordneten Prozess im Shell-Skript beenden:
Oft müssen wir untergeordnete Prozesse beenden, die aus irgendeinem Grund gehängt oder blockiert werden. z.B. Problem mit der FTP-Verbindung.
Es gibt zwei Ansätze:
1) Erstellen eines separaten neuen Elternteils für jedes Kind, das den untergeordneten Prozess überwacht und beendet, sobald das Zeitlimit erreicht ist.
Erstellen Sie test.sh wie folgt:
und beobachten Sie Prozesse, die in einem anderen Terminal den Namen 'test' haben, mit dem folgenden Befehl.
Das obige Skript erstellt 4 neue untergeordnete Prozesse und deren Eltern. Jeder untergeordnete Prozess wird 10 Sekunden lang ausgeführt. Sobald jedoch eine Zeitüberschreitung von 5 Sekunden erreicht ist, werden diese Kinder durch ihre jeweiligen übergeordneten Prozesse getötet. Das Kind kann die Ausführung also nicht abschließen (10 Sekunden). Spielen Sie mit diesen Timings (Schalter 10 und 5), um ein anderes Verhalten zu sehen. In diesem Fall beendet das Kind die Ausführung in 5 Sekunden, bevor das Zeitlimit von 10 Sekunden erreicht ist.
2) Lassen Sie den aktuellen übergeordneten Prozess überwachen und beenden, sobald das Timeout erreicht ist. Dadurch wird kein separates übergeordnetes Element erstellt, um jedes untergeordnete Element zu überwachen. Außerdem können Sie alle untergeordneten Prozesse innerhalb desselben übergeordneten Prozesses ordnungsgemäß verwalten.
Erstellen Sie test.sh wie folgt:
und beobachten Sie Prozesse, die in einem anderen Terminal den Namen 'test' haben, mit dem folgenden Befehl.
Das obige Skript erstellt 4 neue untergeordnete Prozesse. Wir speichern Pids aller untergeordneten Prozesse und durchlaufen sie, um zu überprüfen, ob sie ausgeführt wurden oder noch ausgeführt werden. Der untergeordnete Prozess wird bis zur CMD_TIME-Zeit ausgeführt. Wenn das Zeitlimit für CNT_TIME_OUT erreicht ist, werden alle Kinder vom übergeordneten Prozess getötet. Sie können das Timing wechseln und mit dem Skript herumspielen, um das Verhalten zu sehen. Ein Nachteil dieses Ansatzes besteht darin, dass die Gruppen-ID zum Töten aller untergeordneten Bäume verwendet wird. Der übergeordnete Prozess selbst gehört jedoch zur selben Gruppe, sodass er auch getötet wird.
Möglicherweise müssen Sie dem übergeordneten Prozess eine andere Gruppen-ID zuweisen, wenn Sie nicht möchten, dass das übergeordnete Element getötet wird.
Weitere Details finden Sie hier,
Untergeordneten Prozess im Shell-Skript beenden
quelle
Dieses Skript funktioniert auch:
#/bin/sh while true do echo "Enter parent process id [type quit for exit]" read ppid if [ $ppid -eq "quit" -o $ppid -eq "QUIT" ];then exit 0 fi for i in `ps -ef| awk '$3 == '$ppid' { print $2 }'` do echo killing $i kill $i done done
quelle
Ich weiß, dass das alt ist, aber das ist die bessere Lösung, die ich gefunden habe:
quelle