Ответ 1
После запуска каждого дочернего процесса вы можете получить свой идентификатор с помощью
ID=$!
Затем вы можете использовать сохраненные PID для поиска и уничтожения всех процессов grandchild и т.д., как описано здесь или здесь.
Я пишу bash script, что делает несколько вещей.
Вначале он запускает несколько сценариев монитора, каждый из которых запускает некоторые другие инструменты.
В конце моего основного script я хотел бы убить все, что порождено из моей оболочки.
Итак, это может выглядеть так:
#!/bin/bash
some_monitor1.sh &
some_monitor2.sh &
some_monitor3.sh &
do_some_work
...
kill_subprocesses
Дело в том, что большинство этих мониторов порождают собственные подпроцессы, поэтому (например): killall some_monitor1.sh
не всегда будет помогать.
Любой другой способ справиться с этой ситуацией?
После запуска каждого дочернего процесса вы можете получить свой идентификатор с помощью
ID=$!
Затем вы можете использовать сохраненные PID для поиска и уничтожения всех процессов grandchild и т.д., как описано здесь или здесь.
pkill -P $$
будет соответствовать (просто убивает его собственных потомков)
РЕДАКТОР: Я получил нисходящее зрение, не знаю, почему. В любом случае, здесь есть помощь -P
-P, --parent ppid,...
Only match processes whose parent process ID is listed.
и $$
- это идентификатор процесса самого script
kill $(jobs -p)
Предостережение о состоянии гонки, используя [код ниже], выполняет то, что предложил Юрген, не вызывая ошибки, когда не существует никаких работ
[[ -z "$(jobs -p)" ]] || kill $(jobs -p)
Если вы используете отрицательный PID с kill
, он убьет группу процессов.
Расширение ответа 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 $$
убьет дескрипторы текущего script/shell.
(Проверено на Mac OS 10.9.5. Только зависит от pgrep и kill)
pkill с optioin "-P" должен помочь:
pkill -P $(pgrep some_monitor1.sh)
на странице man:
-P ppid,...
Only match processes whose parent process ID is listed.
Есть несколько обсуждений на linuxquests.org, пожалуйста, проверьте: