Я пытаюсь написать обработчики сигналов в скриптах Bash, тестируя на машине с Ubuntu 16.04. Здесь я использую команду trap :

#!/bin/bash

trap "echo hi!" SIGINT SIGTERM

echo "pid is $$"
while true; do
    sleep 1;
done

После запуска ./test.sh нажатие Ctrl+C дает мне немедленный hi! сообщение под текущим терминалом. Однако kill <pid> под другим терминалом имеет задержку в 1 секунду и выводит hi! ,

Кто-нибудь может сказать, почему есть разница? Есть ли способ, который всегда вызывает команду trap немедленно, независимо от того, что происходит? (как цикл сна).

1 ответ1

2

Кто-нибудь может сказать, почему есть разница?

Ctrl+C тоже sleep , а kill <pid> - нет. По сути, последний путь нуждается в sleep чтобы выйти сам, прежде чем hi! печатается. То, что вы называете "задержкой в 1 секунду", составляет самое большее около 1 секунды и в среднем около 0,5 (это может занять больше времени, если ОС очень занята другими задачами).

Вы можете ясно увидеть разницу, используя

pv -qL 1 <<< "0123456789"

вместо sleep 1 .

Обратите внимание, что

kill -- -<pid>    # note the minus sign before PID

будет посылать сигнал всей группе процессов, так что sleep (или pv), а также.


Есть ли способ, который всегда вызывает команду trap немедленно, независимо от того, что происходит?

Возникает такой вопрос, как обрабатывать сигналы в bash при синхронном выполнении?

Из одного из ответов:

Если bash ожидает завершения команды и получает сигнал, для которого установлена ловушка, ловушка не будет выполнена, пока команда не завершится. Когда bash ожидает асинхронную команду через встроенную функцию wait , прием сигнала, для которого установлена ловушка, заставит встроенную функцию wait немедленно вернуться со статусом выхода больше 128, сразу после чего ловушка будет выполнена.

Итак, запустите вашу внешнюю программу асинхронно и используйте wait . Убей его, используя $! ,

В вашем случае этот метод приводит к следующему быстрому и грязному сценарию:

#!/bin/bash

trap 'kill "$!"; echo hi!' SIGINT SIGTERM

echo "pid is $$"
while true; do
    sleep 1 &
    wait
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .