我正在写一个bash脚本,它做了几件事。
一开始它会启动几个监视器脚本,每个脚本都运行一些其他工具。
在我的主脚本结束时,我想杀死从我的shell中生成的所有东西。
所以,它可能看起来像这样:
#!/bin/bash
some_monitor1.sh &
some_monitor2.sh &
some_monitor3.sh &
do_some_work
...
kill_subprocesses
事实上,这些监视器中的大多数都会产生自己的子进程,所以这样做(例如):killall some_monitor1.sh
并不总是有帮助。
处理这种情况的其他任何方式?
答案 0 :(得分:87)
pkill -P $$
适合(只是杀死它自己的后代)
编辑:我得到了一个downvote,不知道为什么。无论如何这里是-P 的帮助 -P, --parent ppid,...
Only match processes whose parent process ID is listed.
答案 1 :(得分:24)
答案 2 :(得分:12)
如果对kill
使用负PID,则会终止进程组。例如:
kill -- -1234
答案 3 :(得分:9)
kill $(jobs -p)
Rhys Ulerich的建议:
使用[以下代码]警告竞争条件,完成Jürgen所建议的内容,而不会在没有作业时导致错误
[[ -z "$(jobs -p)" ]] || kill $(jobs -p)
答案 4 :(得分:6)
扩展pihentagy的答案,以递归方式杀死所有后代(不只是孩子):
kill_descendant_processes() {
local pid="$1"
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
}
现在
kill_descendant_processes $$
会杀死当前脚本/ shell的内容。
(在Mac OS 10.9.5上测试。仅取决于pgrep并杀死)
答案 5 :(得分:3)
使用选项“-P”可以提供帮助:
pkill -P $(pgrep some_monitor1.sh)
来自手册页:
-P ppid,...
Only match processes whose parent process ID is listed.
有关linux quests.org的一些讨论,请查看:
答案 6 :(得分:1)
我喜欢以下简单的方法:使用带有一些名称/值的环境变量启动子进程,然后使用它来终止子进程。最方便的是使用正在运行的 bash 脚本的进程 ID,即 $$。这也适用于子进程在继承环境时启动另一个子进程。
所以像这样启动子进程:
MY_SCRIPT_TOKEN=$$ some_monitor1.sh &
MY_SCRIPT_TOKEN=$$ some_monitor2.sh &
然后像这样杀死他们:
ps -Eef | grep "MY_SCRIPT_TOKEN=$$" | awk '{print $2}' | xargs kill