Linux 什么';向流程组的所有成员发送信号的最佳方式是什么?
我想杀死一棵完整的进程树。使用任何通用脚本语言执行此操作的最佳方法是什么?我正在寻找一个简单的解决方案。如果您知道传递父进程的pid,下面是一个shell脚本,它应该可以工作:Linux 什么';向流程组的所有成员发送信号的最佳方式是什么?,linux,shell,process,signals,Linux,Shell,Process,Signals,我想杀死一棵完整的进程树。使用任何通用脚本语言执行此操作的最佳方法是什么?我正在寻找一个简单的解决方案。如果您知道传递父进程的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 do
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
brad的答案也是我推荐的,除了如果您使用
--ppid
选项来ps
,您可以完全取消awk
for child in $(ps -o pid -ax --ppid $PPID) do ....... done
你不能说你想杀死的树是否是一个进程组。(如果树是从服务器启动或shell命令行分叉的结果,则通常会出现这种情况。)您可以使用GNU ps发现进程组,如下所示:
ps x -o "%p %r %y %x %c "
如果它是要终止的进程组,只需使用
kill(1)
命令,而不是给它一个进程号,而是给它一个组号的反号。例如,要杀死组5112中的每个进程,请使用kill-TERM---5112
谢谢大家的智慧。我的脚本在退出时留下了一些子进程,而否定提示使事情变得更容易。我编写了此函数,以便在必要时在其他脚本中使用:
# 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():
ps -o pid= --ppid $PPID | xargs kill -9
#/bin/bash
基尔特里(){
本地_pid=$1
局部_sig=${2:--TERM}
kill-stop${u-pid}需要停止在子杀死和父杀死之间快速分叉父对象以生成子对象
对于{u child in$(ps-opid--no headers--ppid${u pid});do
killtree${u child}${u sig}
完成
kill-${u sig}${u pid}
}
如果[$#-eq 0-o$#-gt 2];然后
echo“用法:$(基本名称$0)[信号]”
出口1
fi
基尔特里$@
如果您的系统上有pstree和perl,您可以尝试以下方法:
perl -e 'kill 9, (`pstree -p PID` =~ m/\((\d+)\)/sg)'
在孩子出生之前杀死父母可能更好;否则,父母可能会在自杀前再次生育新的子女。这些将在杀戮中幸存下来 我的ps版本与上述版本不同;也许太老了,所以奇怪的灰色 使用shell脚本而不是shell函数有很多优点 然而,这基本上是一个想法
如果你知道你想要杀死的东西的pid,你通常可以从会话id和同一会话中的所有内容开始。我会仔细检查,但我用这个脚本在我想要终止的循环中启动rsync,而不是像我刚刚终止所有rsync那样启动另一个(因为循环)
kill $(ps -o pid= -s $(ps -o sess --no-heading --pid 21709))
如果你不知道pid,你仍然可以嵌套更多
kill $(ps -o pid= -s $(ps -o sess --no-heading --pid $(pgrep rsync )))
这将杀死所有父进程ID为27888的进程
或更稳健:
CPIDS=$(pgrep -P 27888); (sleep 33 && kill -KILL $CPIDS &); kill -TERM $CPIDS
它会在33秒后停止,并礼貌地要求进程终止
有关终止所有子体的信息,请参阅。要添加到Norman Ramsey的答案中,如果要创建进程组,可能需要查看setId。
函数的作用是创建一个 新会话,如果调用进程为 不是流程组长。在上面 返回调用过程应为 本次新会议的会议负责人 会话,应为过程组 新流程小组组长,以及 应无控制终端。 调用进程的进程组ID 工艺设置应等于 调用进程的进程ID。这个 调用过程应是唯一的 新流程组中的流程和 新会话中唯一的进程 我认为这意味着你可以从一开始就创建一个组。我在php中使用它是为了能够在启动整个进程树之后杀死它
这可能是个坏主意。我对评论很感兴趣 这是我使用bash脚本杀死所有子进程的版本。 它不使用递归,依赖于pgrep命令 使用 killtrees.sh的内容
#!/bin/bash
PID=$1
if [ -z $PID ];
then
echo "No pid specified"
fi
PPLIST=$PID
CHILD_LIST=`pgrep -P $PPLIST -d,`
while [ ! -z "$CHILD_LIST" ]
do
PPLIST="$PPLIST,$CHILD_LIST"
CHILD_LIST=`pgrep -P $CHILD_LIST -d,`
done
SIGNAL=$2
if [ -z $SIGNAL ]
then
SIGNAL="TERM"
fi
#do substring from comma to space
kill -$SIGNAL ${PPLIST//,/ }
我使用了这里描述的方法的一个稍加修改的版本: 看起来是这样的:
kill `pstree -p 24901 | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " "`
其中,24901是母公司的PID
它看起来很难看,但做得很好。修改了志刚的答案:
#!/usr/bin/env bash
set -eu
killtree() {
local pid
for pid; do
kill -stop $pid
local cpid
for cpid in $(pgrep -P $pid); do
killtree $cpid
done
kill $pid
kill -cont $pid
wait $pid 2>/dev/null || true
done
}
cpids() {
local pid=$1 options=${2:-} space=${3:-}
local cpid
for cpid in $(pgrep -P $pid); do
echo "$space$cpid"
if [[ "${options/a/}" != "$options" ]]; then
cpids $cpid "$options" "$space "
fi
done
}
while true; do sleep 1; done &
cpid=$!
for i in $(seq 1 2); do
cpids $$ a
sleep 1
done
killtree $cpid
echo ---
cpids $$ a
灵感来自
与其给它一个进程号,不如给它一个组的否定
号码。和通常的任何命令一样,如果你想要一个正常的参数 以不被解释为开关的
-
开头,在其前面加上-
使用进程组ID(
PGID
)杀死属于同一进程树的所有进程
使用默认信号(终止--$PGID
=15)术语
使用信号kill-9-$PGID
(9)kill
PID
)中检索PGID
(信号kill--$(ps-o pgid=$PID | grep-o'[0-9]*')
)术语
(信号kill-9-$(ps-o pgid=$PID | grep-o'[0-9]*')
)kill
$PID
剩余空间和OSX兼容性的贡献
解释
=>向所有子代和孙代发送信号9(kill-9-“$PGID”
)kill
=>从树的任何进程ID检索进程组ID,不仅是进程-Parent-ID。PGID=$(ps opgid=“$PID”)
的一个变体是ps opgid=$PID
,其中ps-o pgid——没有头$PID
可以被pgid
替换pgrp
但是:
当ps
小于五位且右对齐时插入前导空格,如所注意到的。您可以使用:PID
PGID=$(ps opgid=“$PID”| tr-d”)
来自OSX aps
killtree.sh PID SIGNAL
#!/bin/bash PID=$1 if [ -z $PID ]; then echo "No pid specified" fi PPLIST=$PID CHILD_LIST=`pgrep -P $PPLIST -d,` while [ ! -z "$CHILD_LIST" ] do PPLIST="$PPLIST,$CHILD_LIST" CHILD_LIST=`pgrep -P $CHILD_LIST -d,` done SIGNAL=$2 if [ -z $SIGNAL ] then SIGNAL="TERM" fi #do substring from comma to space kill -$SIGNAL ${PPLIST//,/ }
kill `pstree -p 24901 | sed 's/(/\n(/g' | grep '(' | sed 's/(\(.*\)).*/\1/' | tr "\n" " "`
#!/usr/bin/env bash set -eu killtree() { local pid for pid; do kill -stop $pid local cpid for cpid in $(pgrep -P $pid); do killtree $cpid done kill $pid kill -cont $pid wait $pid 2>/dev/null || true done } cpids() { local pid=$1 options=${2:-} space=${3:-} local cpid for cpid in $(pgrep -P $pid); do echo "$space$cpid" if [[ "${options/a/}" != "$options" ]]; then cpids $cpid "$options" "$space " fi done } while true; do sleep 1; done & cpid=$! for i in $(seq 1 2); do cpids $$ a sleep 1 done killtree $cpid echo --- cpids $$ a
kill -- -PGID
PGID=$(ps -o pgid= $PID | grep -o [0-9]*) kill -TERM -"$PGID" # kill -15 kill -INT -"$PGID" # correspond to [CRTL+C] from keyboard kill -QUIT -"$PGID" # correspond to [CRTL+\] from keyboard kill -CONT -"$PGID" # restart a stopped process (above signals do not kill it) sleep 2 # wait terminate process (more time if required) kill -KILL -"$PGID" # kill -9 if it does not intercept signals (or buggy)
> cat run-many-processes.sh #!/bin/sh echo "ProcessID=$$ begins ($0)" ./child.sh background & ./child.sh foreground echo "ProcessID=$$ ends ($0)" > cat child.sh #!/bin/sh echo "ProcessID=$$ begins ($0)" ./grandchild.sh background & ./grandchild.sh foreground echo "ProcessID=$$ ends ($0)" > cat grandchild.sh #!/bin/sh echo "ProcessID=$$ begins ($0)" sleep 9999 echo "ProcessID=$$ ends ($0)"
> ./run-many-processes.sh & ProcessID=28957 begins (./run-many-processes.sh) ProcessID=28959 begins (./child.sh) ProcessID=28958 begins (./child.sh) ProcessID=28960 begins (./grandchild.sh) ProcessID=28961 begins (./grandchild.sh) ProcessID=28962 begins (./grandchild.sh) ProcessID=28963 begins (./grandchild.sh) > PID=$! # get the Parent Process ID > PGID=$(ps opgid= "$PID") # get the Process Group ID > ps fj PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 28348 28349 28349 28349 pts/3 28969 Ss 33021 0:00 -bash 28349 28957 28957 28349 pts/3 28969 S 33021 0:00 \_ /bin/sh ./run-many-processes.sh 28957 28958 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./child.sh background 28958 28961 28957 28349 pts/3 28969 S 33021 0:00 | | \_ /bin/sh ./grandchild.sh background 28961 28965 28957 28349 pts/3 28969 S 33021 0:00 | | | \_ sleep 9999 28958 28963 28957 28349 pts/3 28969 S 33021 0:00 | | \_ /bin/sh ./grandchild.sh foreground 28963 28967 28957 28349 pts/3 28969 S 33021 0:00 | | \_ sleep 9999 28957 28959 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./child.sh foreground 28959 28960 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./grandchild.sh background 28960 28964 28957 28349 pts/3 28969 S 33021 0:00 | | \_ sleep 9999 28959 28962 28957 28349 pts/3 28969 S 33021 0:00 | \_ /bin/sh ./grandchild.sh foreground 28962 28966 28957 28349 pts/3 28969 S 33021 0:00 | \_ sleep 9999 28349 28969 28969 28349 pts/3 28969 R+ 33021 0:00 \_ ps fj
> pkill -P "$PID" ./run-many-processes.sh: line 4: 28958 Terminated ./child.sh background ./run-many-processes.sh: line 4: 28959 Terminated ./child.sh foreground ProcessID=28957 ends (./run-many-processes.sh) [1]+ Done ./run-many-processes.sh > ps fj PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 28348 28349 28349 28349 pts/3 28987 Ss 33021 0:00 -bash 28349 28987 28987 28349 pts/3 28987 R+ 33021 0:00 \_ ps fj 1 28963 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh foreground 28963 28967 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999 1 28962 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh foreground 28962 28966 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999 1 28961 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh background 28961 28965 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999 1 28960 28957 28349 pts/3 28987 S 33021 0:00 /bin/sh ./grandchild.sh background 28960 28964 28957 28349 pts/3 28987 S 33021 0:00 \_ sleep 9999
> kill -- -"$PGID" # default signal is TERM (kill -15) > kill -CONT -"$PGID" # awake stopped processes > kill -KILL -"$PGID" # kill -9 to be sure > ps fj PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 28348 28349 28349 28349 pts/3 29039 Ss 33021 0:00 -bash 28349 29039 29039 28349 pts/3 29039 R+ 33021 0:00 \_ ps fj
killtree() { local parent=$1 child for child in $(ps -o ppid= -o pid= | awk "\$1==$parent {print \$2}"); do killtree $child done kill $parent }
def killChildren(pid): parent = psutil.Process(pid) for child in parent.get_children(True): if child.is_running(): child.terminate()
kill -- -$( ps opgid= $PID | tr -d ' ' )
init_killtree() { local pid=$1 child for child in $(pgrep -P $pid); do init_killtree $child done [ $pid -ne $$ ] && kill -kill $pid }
function killtree { kill -STOP "$1" ps -e -o pid= -o ppid= | while read -r pid ppid do [[ $ppid = $1 ]] || continue killtree "$pid" || true # Skip over failures done kill -CONT "$1" kill -TERM "$1" }
killall -9 -g someprocessname
pgrep someprocessname | xargs pkill -9 -g
for SIGNAL in TERM KILL; do for CHILD in $(jobs -s|sort -r); do kill -s $SIGNAL $CHILD sleep $MOMENT done done
#!/bin/bash declare -a CMDs=("AAA" "BBB" "CCC" "DDD") for CMD in ${CMDs[*]}; do (sleep 10 & PID=$!; echo "Started $CMD => $PID"; sleep 5; echo "Killing $CMD => $PID"; kill $PID; echo "$CMD Completed.") & done exit;
watch -n1 'ps x -o "%p %r %c" | grep "test" '
#!/bin/bash declare -A CPIDs; declare -a CMDs=("AAA" "BBB" "CCC" "DDD") CMD_TIME=15; for CMD in ${CMDs[*]}; do (echo "Started..$CMD"; sleep $CMD_TIME; echo "$CMD Done";) & CPIDs[$!]="$RN"; sleep 1; done GPID=$(ps -o pgid= $$); CNT_TIME_OUT=10; CNT=0; while (true); do declare -A TMP_CPIDs; for PID in "${!CPIDs[@]}"; do echo "Checking "${CPIDs[$PID]}"=>"$PID; if ps -p $PID > /dev/null ; then echo "-->"${CPIDs[$PID]}"=>"$PID" is running.."; TMP_CPIDs[$PID]=${CPIDs[$PID]}; else echo "-->"${CPIDs[$PID]}"=>"$PID" is completed."; fi done if [ ${#TMP_CPIDs[@]} == 0 ]; then echo "All commands completed."; break; else unset CPIDs; declare -A CPIDs; for PID in "${!TMP_CPIDs[@]}"; do CPIDs[$PID]=${TMP_CPIDs[$PID]}; done unset TMP_CPIDs; if [ $CNT -gt $CNT_TIME_OUT ]; then echo ${CPIDs[@]}"PIDs not reponding. Timeout reached $CNT sec. killing all childern with GPID $GPID.."; kill -- -$GPID; fi fi CNT=$((CNT+1)); echo "waiting since $b secs.."; sleep 1; done exit;
watch -n1 'ps x -o "%p %r %c" | grep "test" '
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
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
rkill [-SIG] pid/name...
#!/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
awk 'BEGIN { p=1390 while ("ps -o ppid,pid"|getline) a[$1]=a[$1]" "$2 o=1 while (o==1) { o=0 split(p, q, " ") for (i in q) if (a[q[i]]!="") { p=p""a[q[i]] o=1 a[q[i]]="" } } system("kill -TERM "p) }'
awk 'BEGIN {p=1390;while ("ps -o ppid,pid"|getline) a[$1]=a[$1]" "$2;o=1;while (o==1) {o=0;split(p, q, " ");for (i in q) {if (a[q[i]]!="") {p=p""a[q[i]];o=1;a[q[i]]=""}}}system("kill -TERM "p)}'
sub(/[0-9]*/, "", p)
killtree() { for p in $(pstree -p $1 | grep -o "([[:digit:]]*)" |grep -o "[[:digit:]]*" | tac);do echo Terminating: $p kill $p done }