Как убить фоновые процессы / задания при выходе из моего сценария оболочки? - PullRequest
163 голосов
/ 11 декабря 2008

Я ищу способ убрать беспорядок, когда мой скрипт верхнего уровня завершается.

Особенно, если я хочу использовать set -e, я бы хотел, чтобы фоновый процесс умер при выходе из скрипта.

Ответы [ 13 ]

0 голосов
/ 01 июля 2015

Я сделал адаптацию ответа @ tokland в сочетании со знаниями из http://veithen.github.io/2014/11/16/sigterm-propagation.html, когда заметил, что trap не срабатывает, если я запускаю процесс переднего плана (не фоновый с &):

#!/bin/bash

# killable-shell.sh: Kills itself and all children (the whole process group) when killed.
# Adapted from http://stackoverflow.com/a/2173421 and http://veithen.github.io/2014/11/16/sigterm-propagation.html
# Note: Does not work (and cannot work) when the shell itself is killed with SIGKILL, for then the trap is not triggered.
trap "trap - SIGTERM && echo 'Caught SIGTERM, sending SIGTERM to process group' && kill -- -$$" SIGINT SIGTERM EXIT

echo $@
"$@" &
PID=$!
wait $PID
trap - SIGINT SIGTERM EXIT
wait $PID

Пример работы:

$ bash killable-shell.sh sleep 100
sleep 100
^Z
[1]  + 31568 suspended  bash killable-shell.sh sleep 100

$ ps aux | grep "sleep"
niklas   31568  0.0  0.0  19640  1440 pts/18   T    01:30   0:00 bash killable-shell.sh sleep 100
niklas   31569  0.0  0.0  14404   616 pts/18   T    01:30   0:00 sleep 100
niklas   31605  0.0  0.0  18956   936 pts/18   S+   01:30   0:00 grep --color=auto sleep

$ bg
[1]  + 31568 continued  bash killable-shell.sh sleep 100

$ kill 31568
Caught SIGTERM, sending SIGTERM to process group
[1]  + 31568 terminated  bash killable-shell.sh sleep 100

$ ps aux | grep "sleep"
niklas   31717  0.0  0.0  18956   936 pts/18   S+   01:31   0:00 grep --color=auto sleep
0 голосов
/ 12 декабря 2012

jobs -p не работает во всех оболочках, если вызывается в под-оболочке, возможно, если его вывод не перенаправлен в файл, а не в канал. (Я предполагаю, что изначально он был предназначен только для интерактивного использования.)

А как насчет следующего:

trap 'while kill %% 2>/dev/null; do jobs > /dev/null; done' INT TERM EXIT [...]

Вызов "jobs" необходим в dash-оболочке Debian, которая не может обновить текущее задание ("%%"), если оно отсутствует.

0 голосов
/ 11 декабря 2008

Итак, скрипт загрузки скрипта. Запустите команду killall (или любую другую, доступную в вашей ОС), которая выполняется, как только скрипт завершится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...