LINUX.ORG.RU

Как правильно закрывать фоновые процессы, запущенные из скрипта, по ^C?

 


1

1

Мне нужно запускать в скриптах фоновые процессы (& в конце).
Но как их все закрывать по CTRL+C?
trap "kill -9 $(jobs -p) $$" 2 не работает потому что job control в скриптах не работает.
Но если добавить set -m, trap вообще перестаёт срабатывать.
___________________________
UPD:
решение оказалось таким:

set -m
trap "kill -9 \$(jobs -p) $$" 0 2 9 15

или таким:
trap "kill -9 %1 $$" 2 9 15

★★★★★

А, тебе убивать только фоновые из скрипта...

Ну так составляй пул pid'ов всех запущенных скриптов (массив, строка). А потом поочередно их убивай.

anonymous ()

Я писал небольшую обёртку для выполнения длительного задания, которое нельзя было бы прервать по Ctrl+C, а вместо этого вывести предупреждение. Завершение скрипта (вместе с фоновыми дочерними заданиями) было по Ctrl+Z. Надеюсь, это может тебе пригодиться.

#!/bin/bash

set -m
pid=

# This is traps for unix signals. You can get all available signals with 'kill -l'
trap trap_ctrl_c 2 3 15
trap trap_ctrl_z 20

function trap_ctrl_c() {
        echo -en '\n*** Warning! Interruption will corrupt the ongoing process. Press Ctrl+Z to stop process. ***\n'
        trap trap_ctrl_c 2 3 15
        trap trap_ctrl_z 20
}

function trap_ctrl_z()
{
        echo -en "\n*** exit... ***\n"
        kill $pid
        exit
}


(
        # *** PUT YOUR STUFF HERE (and remove line with wget) ***
        wget http://cdimage.debian.org/debian-cd/8.2.0/amd64/iso-cd/debian-8.2.0-amd64-CD-1.iso
)&

pid=$!

#echo "process pid is: $$"
#echo "child pid list is: $pid"

# this dummy loop helps us to catch signals in correct way
while true; do
        sleep 60 & wait
done

wait $pid

Pravorskyi ()
Ответ на: комментарий от t184256

оказалось не хватало EXIT для trap'а.
а kill -9 $(jobs -p) нужно вынести в функцию.

по поводу сигнала EXIT: какие ещё сигналы ему передавать, чтоб по ^C всегда срабатывало? 2, 3, 15 надо?

teod0r ★★★★★ ()
Последнее исправление: teod0r (всего исправлений: 2)
Ответ на: комментарий от teod0r

Из твоего примера (измененного):

trap "echo 11111; kill -9 $(jobs -p)" 2
sleep 1m &
Я заметил, что в твоём варианте при исполнении «захваченной» команды jobs ничего не знает о фоновых командах, которые были запущены позже. Но если поменять местами — всё работает.
#!/bin/bash
set -m

sleep 1m &
trap "echo 11111; echo $(jobs -p); kill -9 $(jobs -p)" 2

echo $$
jobs -p

wait
Я пока не уверен, чем можно объяснить такое поведение, ведь выполнение jobs происходит после запуска фонового процесса.

Pravorskyi ()

Когда-то делал так:
1) Запускал свой скрипт в отдельной группе процессов

setsid supescript.sh
2) внутри скрипта
echo $$ >$pidfile
3) убивал так
read pid < ${pidfile}
/bin/kill -$pid 
!!! Negative PID !!!

man : kill [options] <pid> [...] Negative PID values may be used to choose whole process groups; see the PGID column in ps command output.

superuser ★★ ()