Прерывание сна в bash с помощью ловушки сигнала

Я пытаюсь поймать сигнал SIGUSR1 в bash script, который спят через команду sleep:

#!/bin/bash

trap 'echo "Caught SIGUSR1"' SIGUSR1

echo "Sleeping.  Pid=$$"
while :
do
    sleep 10
    echo "Sleep over"
done

Ловушка сигнала работает, но эхо-сообщение не отображается, пока не закончится sleep 10.
По-видимому, обработка сигнала bash ожидает завершения текущей команды до обработки сигнала.

Есть ли способ прервать запущенную команду sleep, как только она получит сигнал, так же, как программа C прервет функцию libc sleep()?

Ответы

Ответ 1

#!/bin/bash

trap 'echo "Caught SIGUSR1"' SIGUSR1

echo "Sleeping.  Pid=$$"
while :
do
   sleep 10 &
   wait $!
   echo "Sleep over"
done

Ответ 2

Просто о wait после sleep, потому что я только что сделал эту ошибку в своем script:

Вы должны использовать wait $! вместо wait, если внутри script вы уже запустили другие процессы в фоновом режиме

Например, wait внутри следующего фрагмента кода будет ждать завершения как process_1, так и sleep 10:

process_1 &
  ...
sleep 10 &
wait  

Если вы используете вместо wait, wait $!, ваш script будет ждать только sleep 10, потому что $! означает PID последнего фонового процесса.

Ответ 3

Заметим, что

sleep infinity &
wait

помещает спать в фоновом режиме и останавливает ожидание с помощью сигнала. Это оставляет бесконечный сон по каждому сигналу!

Замените сон и подождите с помощью

read

и все будет хорошо.