bash 如何杀死shell的所有子进程?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2618403/
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
How to kill all subprocesses of shell?
提问by pihentagy
I'm writing a bash script, which does several things.
我正在编写一个 bash 脚本,它可以做几件事。
In the beginning it starts several monitor scripts, each of them runs some other tools.
一开始它会启动几个监视器脚本,每个脚本都运行一些其他工具。
At the end of my main script, I would like to kill all things that were spawned from my shell.
在我的主脚本结束时,我想杀死所有从我的 shell 中产生的东西。
So, it might looks like this:
所以,它可能看起来像这样:
#!/bin/bash
some_monitor1.sh &
some_monitor2.sh &
some_monitor3.sh &
do_some_work
...
kill_subprocesses
The thing is that most of these monitors spawn their own subprocesses, so doing (for example): killall some_monitor1.sh
will not always help.
问题是这些监视器中的大多数都会产生自己的子进程,因此这样做(例如):killall some_monitor1.sh
并不总是有帮助。
Any other way to handle this situation?
有没有其他方法来处理这种情况?
采纳答案by Péter T?r?k
回答by pihentagy
pkill -P $$
will fit (just kills it's own descendants)
会适合(只是杀死它自己的后代)
EDIT: I got a downvote, don't know why. Anyway here is the help of -P
编辑:我投了反对票,不知道为什么。无论如何这里是-P的帮助
-P, --parent ppid,...
Only match processes whose parent process ID is listed.
and $$
is the process id of the script itself
并且$$
是脚本本身的进程id
回答by Paused until further notice.
If you use a negative PID with kill
it will kill a process group. Example:
如果您使用负 PID,kill
它将杀死一个进程组。例子:
kill -- -1234
kill -- -1234
回答by Jürgen H?tzel
kill $(jobs -p)
Rhys Ulerich's suggestion:
Rhys Ulerich的建议:
Caveat a race condition, using [code below] accomplishes what Jürgen suggested without causing an error when no jobs exist
警告竞争条件,使用 [下面的代码] 完成 Jürgen 的建议,而不会在不存在作业时导致错误
[[ -z "$(jobs -p)" ]] || kill $(jobs -p)
回答by Adam Cath
Extending pihentagy's answer to recursively kill all descendants (not just children):
扩展 pihentagy 的答案以递归地杀死所有后代(不仅仅是孩子):
kill_descendant_processes() {
local pid=""
local and_self="${2:-false}"
if children="$(pgrep -P "$pid")"; then
for child in $children; do
kill_descendant_processes "$child" true
done
fi
if [[ "$and_self" == true ]]; then
kill -9 "$pid"
fi
}
Now
现在
kill_descendant_processes $$
will kill descedants of the current script/shell.
将杀死当前脚本/shell 的后代。
(Tested on Mac OS 10.9.5. Only depends on pgrep and kill)
(在 Mac OS 10.9.5 上测试。仅依赖于 pgrep 和 kill)
回答by ybyygu
pkill with optioin "-P" should help:
带有选项“-P”的 pkill 应该会有所帮助:
pkill -P $(pgrep some_monitor1.sh)
from man page:
从手册页:
-P ppid,...
Only match processes whose parent process ID is listed.
There are some discussions on linuxquests.org, please check:
linuxquests.org 上有一些讨论,请查看: