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.

1voto

lyman Punkte 173

Wenn Sie pstree und perl auf Ihrem System haben, können Sie dies versuchen:

perl -e 'kill 9, (`pstree -p PID` =~ m/\((\d+)\)/sg)'

1voto

ps -o pid= --ppid $PPID | xargs kill -9

1voto

Orsiris de Jong Punkte 2367

Das Folgende wurde auf 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 terminiert werden müssen. Das zweite Argument ist ein Boolescher Wert, der bestimmt, ob die Eltern-Pid ebenfalls terminiert werden muss.

KillChilds() {
        local pid="${1}"
        local self="${2:-false}"

        if children="$(pgrep -P "$pid")"; then
                for child in $children; do
                        KillChilds "$child" true
                done
        fi

        if [ "$self" == true ]; then
                kill -s SIGTERM "$pid" || (sleep 10 && kill -9 "$pid" &)
        fi
}

KillChilds $$ > /dev/null 2>&1

Dies sendet SIGTERM an jeden Kind-/Enkelprozess innerhalb eines Shell-Skripts und wenn SIGTERM nicht erfolgreich ist, wartet es 10 Sekunden und sendet dann kill.


Frühere Antwort:

Das Folgende funktioniert auch, wird aber unter BSD die Shell selbst beenden.

KillSubTree() {
    local parent="${1}"
    for child in $(ps -o pid=$parent); do
            if [ $$ -ne $child ]; then (kill -s SIGTERM $child || (sleep 10 && kill -9 $child & )) > /dev/null 2>&1 ; fi
    done
}
# Example lanch from within script
KillSubTree $$ > /dev/null 2>&1

1voto

Danke für eure Weisheit, Leute. Mein Skript hat beim Beenden einige Kindprozesse hinterlassen und die Verneinung Tipp machte die Sache einfacher. Ich habe diese Funktion geschrieben, damit sie bei Bedarf in anderen Skripten verwendet werden kann:

# 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
}

Zum Wohl.

1voto

Peter Steier Punkte 41

Ich entwickle die Lösung von zhigang, xyuri und solidsneck weiter:

 #!/bin/bash

if 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." ; 
        return 1 ;
      fi ;
    # this avoids that children are spawned or disappear.
    kill -SIGSTOP $2 ;

    _children=$(ps -o pid --no-headers --ppid $2) ;        
    _success=0 
    for _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 der Vorfahren, was bei den bisherigen Lösungen zu einer Flut von Kindprozessen führt.

Die Prozesse werden ordnungsgemäß gestoppt, bevor die Child-Liste ermittelt wird, so dass keine neuen Children erstellt werden oder verschwinden.

Nach dem Beenden müssen die angehaltenen Aufträge fortgesetzt werden, um aus dem System zu verschwinden.

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