467 Stimmen

Wie kann man am besten ein Signal an alle Mitglieder einer Prozessgruppe senden?

Ich möchte einen ganzen Prozessbaum töten. Wie kann ich das am besten mit einer der gängigen Skriptsprachen erreichen? Ich bin auf der Suche nach einer einfachen Lösung.

12voto

Tomasz Werszko Punkte 349

Ich verwende eine leicht abgewandelte Version einer hier beschriebenen Methode: https://stackoverflow.com/a/5311362/563175

Es sieht also so aus:

kill `pstree -p 24901 | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " "`

wobei 24901 die PID der Eltern ist.

Er sieht ziemlich hässlich aus, erfüllt aber seine Aufgabe perfekt.

11voto

x-yuri Punkte 13561

Geänderte Version der Antwort von zhigang:

#!/usr/bin/env bash
set -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  "
        fi
    done
}

while true; do sleep 1; done &
cpid=$!
for i in $(seq 1 2); do
    cpids $$ a
    sleep 1
done
killtree $cpid
echo ---
cpids $$ a

11voto

tanager Punkte 171

Ich kann keinen Kommentar abgeben (nicht genug Ansehen), also bin ich gezwungen, einen neuen Antwort auch wenn dies keine wirkliche Antwort ist.

Es gibt ein kleines Problem mit der ansonsten sehr schönen und gründlichen Antwort von @olibre vom 28. Februar. Die Ausgabe von ps opgid= $PID enthält führende Leerzeichen für eine PID, die kürzer als fünf Ziffern ist, weil ps die Spalte ausrichtet (die Zahlen rechts ausrichtet). In der gesamten Befehlszeile ergibt dies ein negatives Vorzeichen, gefolgt von einem oder mehreren Leerzeichen, gefolgt von der Gruppe PID. Eine einfache Lösung ist die Eingabe von ps a tr um Leerzeichen zu entfernen:

kill -- -$( ps opgid= $PID | tr -d ' ' )

10voto

Kim Stebel Punkte 41038

Brads Antwort ist das, was ich auch empfehlen würde, mit dem Unterschied, dass man auf die awk ganz, wenn Sie die --ppid Option zu ps .

for child in $(ps -o pid -ax --ppid $PPID) do ....... done

9voto

hajamie Punkte 2728

Um die Antwort von Norman Ramsey zu ergänzen, kann es sich lohnen, einen Blick auf setsid zu werfen, wenn Sie eine Prozessgruppe erstellen möchten.
http://pubs.opengroup.org/onlinepubs/009695399/functions/setsid.html

Die Funktion setsid() erzeugt eine neue Sitzung, wenn der aufrufende Prozess nicht der Anführer einer Prozessgruppe ist. Bei Rückkehr ist der aufrufende Prozess der der Sitzungsleiter dieser neuen Sitzung, ist der Prozessgruppenleiter Leiter einer neuen Prozessgruppe und darf kein kontrollierendes Terminal haben. Die Prozessgruppen-ID des aufrufenden Prozesses wird gleich der Prozess-ID des aufrufenden Prozesses. Die Adresse aufrufende Prozess muss der einzige sein, der Prozess in der neuen Prozessgruppe und der einzige Prozess in der neuen Sitzung.

Daraus schließe ich, dass Sie eine Gruppe aus dem Startprozess heraus erstellen können. Ich habe dies in php benutzt, um einen ganzen Prozessbaum nach dem Start zu beenden.

Das könnte eine schlechte Idee sein. Ich wäre an Kommentaren interessiert.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X