Linux 向进程组的所有成员发送信号的最佳方式是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/392022/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 16:49:10  来源:igfitidea点击:

What's the best way to send a signal to all members of a process group?

linuxshellprocesssignals

提问by Adam Peck

I want to kill a whole process tree. What is the best way to do this using any common scripting languages? I am looking for a simple solution.

我想杀死整个进程树。使用任何常用脚本语言执行此操作的最佳方法是什么?我正在寻找一个简单的解决方案。

采纳答案by Norman Ramsey

You don't say if the tree you want to kill is a single process group. (This is often the case if the tree is the result of forking from a server start or a shell command line.) You can discover process groups using GNU ps as follows:

您不会说要杀死的树是否是单个进程组。(如果树是从服务器启动或 shell 命令行分叉的结果,则通常是这种情况。)您可以使用 GNU ps 发现进程组,如下所示:

 ps x -o  "%p %r %y %x %c "

If it is a process group you want to kill, just use the kill(1)command but instead of giving it a process number, give it the negationof the group number. For example to kill every process in group 5112, use kill -TERM -- -5112.

如果它是您要杀死的进程组,只需使用该kill(1)命令,而不是给它一个进程号,而是给它组号的否定。例如,要杀死组 5112 中的每个进程,请使用kill -TERM -- -5112.

回答by brad.lane

if you know pass the pid of the parent process, here's a shell script that should work:

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

回答by Kim Stebel

brad's answer is what I'd recommend too, except that you can do away with awkaltogether if you use the --ppidoption to ps.

布拉德的答案是什么,我建议过,但你可以不设awk干脆如果你使用的--ppid选项ps

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

回答by Norman Ramsey

Thanks for your wisdom, folks. My script was leaving some child processes on exit and the negationtip made things easier. I wrote this function to be used in other scripts if necessary:

谢谢你的智慧,伙计们。我的脚本在退出时留下了一些子进程,否定提示使事情变得更容易。如有必要,我编写了此函数以在其他脚本中使用:

# 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  in
        -x) [ -n "" ] && kill -9 - || kill -9 -$$ ;;
        "") mainpid=$$ ;;
         *) mainpid= ;;
    esac
    prid=$(ps ax -o pid,pgid | grep $mainpid)
    prid=${prid//$mainpid/}
    kill -9 $prid 2>/dev/null
    return
}

Cheers.

干杯。

回答by Norman Ramsey

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

回答by zhigang

To kill a process tree recursively, use killtree():

要递归地终止进程树,请使用 killtree():

#!/bin/bash

killtree() {
    local _pid=
    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 
perl -e 'kill 9, (`pstree -p PID` =~ m/\((\d+)\)/sg)'
) <pid> [signal]" exit 1 fi killtree $@

回答by lyman

if you have pstree and perl on your system, you can try this:

如果你的系统上有 pstree 和 perl,你可以试试这个:

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

_pid=
_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

回答by Peter Steier

It is probably better to kill the parent before the children; otherwise the parent may likely spawn new children again before he is killed himself. These will survive the killing.

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

My version of ps is different from that above; maybe too old, therefore the strange grepping...

我的ps版本和上面的不一样;也许太老了,因此奇怪的 grepping ......

To use a shell script instead of a shell function has many advantages...

使用 shell 脚本代替 shell 函数有很多优点......

However, it is basically zhigangs idea

不过基本都是志刚的想法



kill $(ps -o pid= -s $(ps -o sess --no-heading --pid 21709))

回答by Morgan

If you know the pid of the thing you want to kill, you can usually go from the session id, and everything in the same session. I'd double check, but I used this for scripts starting rsyncs in loops that I want to die, and not start another (because of the loop) as it would if I'd just killall'd rsync.

如果你知道你想要杀死的东西的 pid,你通常可以从会话 id 和同一个会话中的所有内容中获取。我会仔细检查,但我将它用于在我想死的循环中启动 rsyncs 的脚本,而不是像我只是 killall'd rsync 那样启动另一个(因为循环)。

kill $(ps -o pid= -s $(ps -o sess --no-heading --pid $(pgrep rsync )))

If you don't know the pid you can still nest more

如果你不知道 pid 你仍然可以嵌套更多

pkill -TERM -P 27888

回答by Onlyjob

CPIDS=$(pgrep -P 27888); (sleep 33 && kill -KILL $CPIDS &); kill -TERM $CPIDS

This will kill all processes that have the parent process ID 27888.

这将终止所有具有父进程 ID 27888 的进程。

Or more robust:

或者更强大:

##代码##

which schedule killing 33 second later and politely ask processes to terminate.

哪个计划在 33 秒后终止并礼貌地要求进程终止。

See this answerfor terminating all descendants.

请参阅此答案以终止所有后代。