Search code examples
bashtimeout

Bash: is there a way to execute a command if another command times out?


I need to run a command with the timeout function, so that if it is not executed in x time, then the script shall start from the beginning, otherwise it can proceed and execute other commands. Can I do that?

I already tried to use case, but it works as long as I use one, if use two cases it gives me an error. Does anybody know how to do it with timeout? Maybe using an user-defined signal like -s USR1, but I don't know how to set that up and if I can execute a command with a signal :/


Solution

  • If some_command completes within 10 seconds, this will continue on with the rest of the script. If some_command times out, then it is repeated until it doesn't time out:

    while timeout 10 some_command; [ $? -eq 124 ]
    do
       :
    done
    echo "Continuing on with script"
    

    How it works

    If a command times out, then, by default, timeout exits with code 124. We can use this to test whether the command timed out and, hence, whether it needs to be repeated. In more detail:

    • while timeout 10 some_command; [ $? -eq 124 ]; do

      This starts a while loop by executing some_command with a 10 second timeout and then testing whether the exit code from timeout is 124 or not. If it is 124, then the while-loop repeats.

    • :

      The command : is a no-op. We don't need any command within the body of the while loop, we use this command.

    • done

      This marks the end of the while loop.

    Special case: ill-behaved commands

    This assumes that some_command responds responsibly to the TERM signal. If it doesn't, the exit code will be 128+9 instead of 124.

    Documentation

    From man timeout:

    If the command times out, and --preserve-status is not set, then exit with status 124. Otherwise, exit with the status of COMMAND. If no signal is specified, send the TERM signal upon timeout. The TERM signal kills any process that does not block or catch that signal. It may be necessary to use the KILL (9) signal, since this signal cannot be caught, in which case the exit status is 128+9 rather than 124.