Thursday, 31 January 2013

bash signal handling

A signal trap will not be executed while bash is implicitly waiting for an external command to complete.

I mean:

#! /bin/bash



trap "echo signal" 10
( sleep 1 ; kill -s 10 $$ ) &


sleep 5

We would expect the word signal to be emitted after 1 second, but the signal handler will not run until the sleep 5 is complete.

However, the built-in bash command wait does not have that problem, and so we can run the task in the background and immediately wait as in this example where the signal runs after 1 second.

#! /bin/bash



trap "echo signal" 10
( sleep 1 ; kill -s 10 $$ ) &


<&0 sleep 5 & wait

The <&0 is required to cover the case that the background command needs to read stdin which would otherwise not be connected for a background command.

The script also quits after 1 second even though the sleep is still running, so this variant detects if the background is still running and waits again:

#! /bin/bash



trap "echo signal" 10
( sleep 1 ; kill -s 10 $$ ) &


sleep 5 & wait
kill -s 0 $! &>- && wait

Of course this is insufficient for 2 reasons; the extra wait should be in a loop, but worse, the exit code is lost.

No comments:

Post a Comment