Как распространить сигнал через набор сценариев?

У меня есть набор сценариев, которыми управляет основной. Я хочу захватить сигнал ctrl+c в основном сценарии и распространить его другим. Другие сценарии должны захватить этот сигнал также (из основного сценария) и сделать некоторую очистку...

Я попытался отправить kill -s SIGINT детям, но они кажутся, что не могут поймать сигнал (даже если trap 'Cleanup' SIGINT будучи определенным на дочерних сценариях)

Какие-либо подсказки, как понять это?

21
задан Jolta 12 April 2017 в 08:41
поделиться

3 ответа

Я не уверен, что вы имеете в виду, говоря «другие сценарии должны перехватывать этот сигнал от основного сценария»? Как сценарий подпроцесса может использовать код в основном сценарии для перехвата сигнала?

Я не хочу пытаться написать для вас много кода, потому что я не знаю точно, что вы имеете в виду под «сценариями, управляемыми основным сценарием». "либо, но, предположительно, вы запускаете некоторые подпроцессы, а затем имеете цикл управления, который проверяет, завершились ли другие сценарии, и может получить их статус выхода? Если это так, то для меня важнее всего, чтобы каждый скрипт выполнял свой собственный захват и очистку. Когда основной сценарий перехватывает сигнал, он может при желании передать сигнал всем потомкам (через kill -s pid ). Когда дочерний процесс перехватывает сигнал, он может вернуть статус выхода, указывающий, что он был завершен этим сигналом. Затем основной модуль может обрабатывать этот статус выхода соответствующим образом - возможно, таким же образом, как если бы он сам получил этот конкретный сигнал. (Функции оболочки - ваш друг.)

0
ответ дан 29 November 2019 в 21:47
поделиться

Следующий пример демонстрирует родительский скрипт, который что-то делает (sleep 5) после запуска двух дочерних, которые делают что-то свое (также sleep 5). Когда родитель выходит (по любой причине), он сигнализирует дочерним программам о завершении работы (не SIGINT, завершение работы сигнализируется SIGTERM, также по умолчанию используется сигнал kill). После получения SIGTERM дочерние программы выполняют свои действия. Если дочерние программы являются собственными скриптами, я рекомендую вам изменить ловушку на TERM на ловушку на EXIT, чтобы дочерние программы убирались независимо от причины их завершения (если только она отлавливается).

Обратите внимание на использование wait. Bash не прерывает выполнение не встроенных команд, когда получает сигнал. Вместо этого он ждет их завершения и обрабатывает сигнал после завершения команды. Если вы используете wait, bash немедленно прекращает ожидание и обрабатывает сигнал сразу же.

#!/usr/bin/env bash

trap 'echo parent shutting down; kill $(jobs -p)' EXIT

{ trap 'echo child 1 signaled' TERM; sleep 5 & wait; } &
{ trap 'echo child 2 signaled' TERM; sleep 5 & wait; } &

sleep 5
19
ответ дан 29 November 2019 в 21:47
поделиться

ГЛАВНЫЙ ЗАГОЛОВОК РОДИТЕЛЬСКОГО СКРИПТА ПЕРЕД ГЛАВНЫМ ЦИКЛОМ :::

#Catch control-c and clean up testd instances if necessary
cleanup () {
    clear
    echo "Caught Signal.  Shutting Down MAIN."
    if [ "$MAIN_on" -eq 1 ]
    then
    M_shutdown
    fi
    exit 1
  }

В основной части скрипта, когда вы порождаете подпроцессы, вы поддерживаете массив с идентификаторами процессов каждого из них. Чтобы загрузить PID в массив, установите значение последнего порожденного процесса, например. помещайте следующее после каждого спауна суб-оболочки.

proc_id_array[1]=$!

Содержимое M_shutdow будет примерно таким ...

M_shutdown () {

    if [ "$MAIN_on" -eq 1 ]
    then
    echo "Stopping Main"
    echo "shutting down active subscripts"
    count_proc_id=1


while [ "$count_proc_id" -lt "$max_proc_id" ]
        do

            kill ${proc_id_array[$count_proc_id]} > /dev/null 2>&1
            DATE=$(date +%m%d%y-%k:%M)
            echo "$DATE: ${proc_name_array[$count_proc_id]} \(PID: ${proc_id_array[$count_proc_id]}\) stopped." >> $logfile             
            proc_id_array[$count_proc_id]="A"
            count_proc_id=`expr $count_proc_id + 1`
        done


        echo "MAIN stopped"
        MAIN_on=0

        sleep 5
        else
        echo "MAIN already stopped."
        sleep 1
        fi
    }
0
ответ дан 29 November 2019 в 21:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: