John Morris
John Morris

Reputation: 721

Interrupt sleep in bash with a signal trap

I'm trying to catch the SIGUSR1 signal in a bash script that is sleeping via the sleep command:

#!/bin/bash

trap 'echo "Caught SIGUSR1"' SIGUSR1

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

The signal trap works, but the message being echoed is not displayed until the sleep 10 has finished.
It appears the bash signal handling waits until the current command finished before processing the signal.

Is there a way to have it interrupt the running sleep command as soon as it gets the signal, the same way a C program would interrupt the libc sleep() function?

Upvotes: 52

Views: 26337

Answers (3)

Hans Klünder
Hans Klünder

Reputation: 2292

#!/bin/bash

trap 'echo "Caught SIGUSR1"' SIGUSR1

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

Upvotes: 67

Echoes_86
Echoes_86

Reputation: 303

Just a point about the wait after the sleep because I've just made this error in my script:

You should use wait $! instead of wait if, inside your script, you already launched other processes in background

For example, the wait inside the next snippet of code will wait for the termination of both process_1 and sleep 10:

process_1 &
  ...
sleep 10 &
wait  

If you use, instead of wait, wait $! your script will wait only for sleep 10, because $! means PID of last backgrounded process.

Upvotes: 17

dirk
dirk

Reputation: 69

Remark that

sleep infinity &
wait

puts the sleep in background, and stops the wait with the signal. This leaves an infinite sleep behind on every signal !

Replace the sleep and wait with

read

and you will be fine.

Upvotes: 6

Related Questions