我想杀死整个进程树。使用通用脚本语言实现这一目标的最佳方法是什么?我在寻找一个简单的解决办法。


当前回答

受到ysth评论的启发

kill -- -PGID

与其给它一个进程号,不如给它一个组的否定 号码。像往常一样,几乎任何命令,如果你想要一个正常的参数 以“-”开头,不被解释为开关,在“——”前面

其他回答

要递归地杀死进程树,请使用killtree():

#!/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 killing
    for _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 1
fi

killtree $@

输入ps -ef检查进程id。 通过输入Kill -9 <pid>来终止进程

如果你想按名称杀死一个进程:

killall -9 -g someprocessname

or

pgrep someprocessname | xargs pkill -9 -g

下面的代码已经在FreeBSD, Linux和MacOS X上进行了测试,只依赖于pgrep和kill (ps -o版本在BSD下不工作)。第一个参数是父pid,子pid必须被终止。第二个参数是一个布尔值,用于确定父pid是否也必须终止。

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

这将向shell脚本中的任何子/孙辈进程发送SIGTERM,如果SIGTERM没有成功,它将等待10秒,然后发送kill。


答:早些时候

下面的代码也可以工作,但是会在BSD上杀死shell本身。

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
ps -o pid= --ppid $PPID | xargs kill -9