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


当前回答

如果你知道传递父进程的pid,下面这个shell脚本应该可以工作:

for child in $(ps -o pid,ppid -ax | \
   awk "{ if ( \$2 == $pid ) { print \$1 }}")
do
  echo "Killing child process $child because ppid = $pid"
  kill $child
done

其他回答

我进一步开发了志刚、木uri和固颈的溶液:

 #!/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

这个版本将避免杀死它的祖先进程——在以前的解决方案中,这会导致大量的子进程。

在确定子列表之前适当地停止进程,这样就不会创建或消失新的子列表。

停止的作业被杀死后,必须继续执行,才能从系统中消失。

在杀死孩子之前杀死父母可能更好;否则,父母可能会在他自杀之前再次繁殖新的孩子。这些会在杀戮中幸存下来。

我的ps版本和上面的不一样;也许太老了,所以奇怪的握手……

使用shell脚本而不是shell函数有很多优点…

然而,这基本上是志刚的想法


#!/bin/bash
if test $# -lt 1 ; then
    echo >&2 "usage: kiltree pid (sig)"
fi ;

_pid=$1
_sig=${2:-TERM}
_children=$(ps j | grep "^[ ]*${_pid} " | cut -c 7-11) ;
echo >&2 kill -${_sig} ${_pid}
kill -${_sig} ${_pid}
for _child in ${_children}; do
    killtree ${_child} ${_sig}
done

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

killall -9 -g someprocessname

or

pgrep someprocessname | xargs pkill -9 -g

谢谢你们的智慧。我的脚本在退出时留下了一些子进程,而否定提示使事情变得更容易。我写这个函数是为了在其他脚本中使用:

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

欢呼。

我知道这很老了,但这是我找到的更好的解决方案:

killtree() { 
    for p in $(pstree -p $1 | grep -o "([[:digit:]]*)" |grep -o "[[:digit:]]*" | tac);do
        echo Terminating: $p 
        kill $p
    done
}