Уничтожение подпроцессов после завершения или уничтожения скрипта

Уничтожение подпроцессов после завершения или уничтожения скрипта

Допустим, у меня есть такой скрипт:

#!/usr/bin/env zsh
./subscript.sh &
# do stuff
...
# do more stuff

Я бы хотел, чтобы запущенный процесс subscript.sh(и любые инициированные им процессы) полностью завершались в следующих случаях:

  1. Скрипт выше завершает работу
  2. Скрипт выше будет завершен по любой причине.

Как я могу обеспечить выполнение вышеизложенного? Это автоматически делается оболочкой?

решение1

Оболочка определенно не будет спонтанно завершать свои подпроцессы — в конце концов, фоновое задание должно работать в фоновом режиме и не заботиться о жизни своего родителя. (Интерактивная оболочка в некоторых обстоятельствах завершает свои подпроцессы при выходе — что не всегда желательно, поэтомуnohup.)

Вы можете заставить скрипт оболочки убивать свои фоновые задания, когда он завершается или убивается перехватываемым сигналом. Запишите идентификаторы процессов заданий и убейте их из ловушки. Обратите внимание, что это убивает только задания (то есть исходный процесс, запущенный в фоновом режиме), а не их подпроцессы.

jobs=()
trap '((#jobs == 0)) || kill $jobs' EXIT HUP TERM INT
subscript1 & jobs+=($!)
subscript2 & jobs+=($!)

Если вы хотите быть уверены, что убиваете все процессы и их подпроцессы, требуется больше планирования. Один из методов — сделать так, чтобы все процессы открывали уникальный файл. Чтобы убить их всех, убейте все процессы, у которых открыт этот файл. Подпроцесс может выйти, закрыв файл.

#!/bin/sh
lock_file=$(mktemp)
exec 3<"$lock_file"
your_script
status=$?
exec 3<&-
fuser -k "$lock_file"
exit $status

решение2

Вы можете перехватить EXIT и отправить сигнал группе процессов скрипта.

на линуксе

trap 'kill -SIGTERM 0' EXIT

на FreeBSD

trap 'kill -15 -$$' EXIT

SIGKILLэто единственный сигнал, где это не сработает, так как скрипт будет завершен безоговорочно.

Связанный контент