Соберите идентификаторы процессов, завершите фоновые процессы при выходе.
#!/bin/bash
killbg() {
for p in "${pids[@]}" ; do
kill "$p";
done
}
trap killbg EXIT
pids=()
background job 1 &
pids+=($!)
background job 2... &
pids+=($!)
foreground job
Перехват EXIT
запускает функцию при выходе из оболочки, независимо от причины. Вы можете изменить это на trap killbg SIGINT
, чтобы запускать его только на ^C
.
Это не проверяет, завершился ли один из фоновых процессов до того, как скрипт попытается выстрелить в них. Если они это сделают, вы можете получить ошибки или, что еще хуже, выстрелить не в тот процесс.
Или убить их по идентификатору работы. Давайте прочитаем вывод jobs
, чтобы выяснить, какие из них все еще активны.
#!/bin/bash
killjobs() {
for x in $(jobs | awk -F '[][]' '{print $2}' ) ; do
kill %$x
done
}
trap killjobs EXIT
sleep 999 &
sleep 1 &
sleep 999 &
sleep 30
Если вы запускаете фоновые процессы, которые порождают другие процессы (например, подоболочку: (sleep 1234 ; echo foo) &
), вам необходимо включить управление заданиями с помощью set -m
( «режим монитора»), чтобы это работало. В противном случае завершается только ведущий процесс.