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


当前回答

只使用属于该组的进程名删除该组:

kill -- -$(ps -ae o pid,pgrp,cmd | grep "[e]xample.py" | awk '{print $2}' | tail -1)

这是对olibre的答案的修改,但你不需要知道PID,只需要知道组中成员的名字。

解释:

要获得组id,您可以使用如下所示的参数执行ps命令,为您的命令grep它,但是使用引号格式化example.py,并使用括号作为第一个字母(这将过滤掉grep命令本身),然后通过awk过滤它以获得第二个字段,即组id。尾部的-1可以去除重复的组id。您使用$()语法将所有这些放到一个变量中,瞧——您得到了组id。用$(mess)替换上面的-groupid。

其他回答

我不能评论(没有足够的声誉),所以我被迫添加一个新的答案,即使这不是一个真正的答案。

@olibre在2月28日给出了一个非常好的、彻底的回答,但有一个小问题。ps opgid= $PID的输出将包含小于5位的PID的前导空格,因为ps正在对列进行对齐(将数字右对齐)。在整个命令行中,这会导致一个负号,后面跟着空格(s),然后是组PID。简单的解决方案是通过管道将ps传送到tr以删除空格:

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

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

killall -9 -g someprocessname

or

pgrep someprocessname | xargs pkill -9 -g

brad的答案也是我推荐的,除了如果你使用——ppid选项ps,你可以完全放弃awk。

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

如果你知道传递父进程的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

只使用属于该组的进程名删除该组:

kill -- -$(ps -ae o pid,pgrp,cmd | grep "[e]xample.py" | awk '{print $2}' | tail -1)

这是对olibre的答案的修改,但你不需要知道PID,只需要知道组中成员的名字。

解释:

要获得组id,您可以使用如下所示的参数执行ps命令,为您的命令grep它,但是使用引号格式化example.py,并使用括号作为第一个字母(这将过滤掉grep命令本身),然后通过awk过滤它以获得第二个字段,即组id。尾部的-1可以去除重复的组id。您使用$()语法将所有这些放到一个变量中,瞧——您得到了组id。用$(mess)替换上面的-groupid。