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

#shell #sh #signals

#оболочка #sh #сигналы

Вопрос:

Если я посылаю сигнал с помощью kill , кажется, что он ждет, пока текущая программа (в этом примере sleep 1000 ) не завершит выполнение. Однако, когда я вместо этого отправляю SIGINT нажатием Ctrl C в оболочке, он немедленно получает прерывание.

Однако я хочу, чтобы прерывание было получено сразу после отправки сигнала через kill . Кроме того, почему он ведет себя так, как я бы хотел, когда я нажимаю Ctrl C ?

 #!/usr/bin/env sh
int_after_a_while() {
    local pid=$1
    sleep 2
    echo "Attempting to kill $pid with SIGINT"
    # Here I want to kill the process immediately, but it waits until sleep finishes
    kill -s INT $pid
}

trap "echo Interrupt received!" INT
int_after_a_while $ amp;
sleep 1000
 

Я был бы признателен за любую помощь по этому вопросу. Заранее спасибо!

Комментарии:

1. Что именно вы используете в качестве своей kill команды? Вы имеете в kill виду команду, которая у вас есть в конце int_after_a_while() ?

2. Да, извините, если это не было ясно из первоначального вопроса.

3. Я думаю, что ваш ответ здесь (я не хочу красть чужой кредит, давая свой собственный ответ): unix.stackexchange.com/a/282631/392334

Ответ №1:

Как указано в ссылочном ответе https://unix.stackexchange.com/questions/282525/why-did-my-trap-not-trigger/282631#282631 оболочка обычно ожидает завершения работы утилиты, прежде чем запускать ловушку. Некоторые альтернативы:

  • Запустите длительный процесс в фоновом режиме, затем дождитесь его, используя wait встроенный. Когда во время такого ожидания принимается захваченный сигнал, ожидание прерывается и захватывается ловушка. К сожалению, статус выхода wait не различает дочерний процесс, завершающийся по сигналу, и возникающую ловушку. Например
     sleep 1000 amp;
    p=$!
    wait "$p"
 
  • Отправьте сигнал всей группе процессов через kill -s INT 0 . Эффект очень похож на то, если бы пользователь нажал Ctrl C, но может быть более экстремальным, чем вы хотите, если ваш скрипт запускается из другого скрипта.
  • Используйте оболочку, такую как zsh или FreeBSD sh, которая поддерживает set -o trapsasync , что позволяет запускать ловушки в ожидании задания переднего плана.