Terminating an infinite loop

You can stop and put your job in background while it's running using ctrl+z. Then you can kill your job with:

$ kill %1

Where [1] is your job number.


Check the exit status of the command. If the command was terminated by a signal the exit code will be 128 + the signal number. From the GNU online documentation for bash:

For the shell’s purposes, a command which exits with a zero exit status has succeeded. A non-zero exit status indicates failure. This seemingly counter-intuitive scheme is used so there is one well-defined way to indicate success and a variety of ways to indicate various failure modes. When a command terminates on a fatal signal whose number is N, Bash uses the value 128+N as the exit status.

POSIX also specifies that the value of a command that terminated by a signal is greater than 128, but does not seem to specify its exact value like GNU does:

The exit status of a command that terminated because it received a signal shall be reported as greater than 128.

For example if you interrupt a command with control-C the exit code will be 130, because SIGINT is signal 2 on Unix systems. So:

while [ 1 ]; do COMMAND; test $? -gt 128 && break; done

I would say it might be best to put your infinite loop in a script and handle signals there. Here's a basic starting point. I'm sure you'll want to modify it to suit. The script uses trap to catch ctrl-c (or SIGTERM), kills off the command (I've used sleep here as a test) and exits.

cleanup ()
{
kill -s SIGTERM $!
exit 0
}

trap cleanup SIGINT SIGTERM

while [ 1 ]
do
    sleep 60 &
    wait $!
done

Tags:

Bash

Signals