read

EDIT: This can be safely replaced by timeout

Sometimes, in a shell script, you need to run a command that might go on forever (or an amount of time long enough to be called forever) due to poor coding of the software and wrong external conditions (network down or overloaded, overloaded system, a changed private key, etc).

In order to avoid this situations, here's a small shell script that will execute any command with a guaranteed timeout:

#!/bin/bash

timeout=$1
command=$2

check_pid_name()
{
        command=$1
        childpid=$2
        [ -d /proc/$childpid ] || return 1
        [ $(grep -c $command /proc/$childpid/cmdline 2>/dev/null) -gt 0 ] && return 0 || return 1
}

[ -z "$command" ] && echo "I need a command to run">&2 && exit 1

[ $# -eq 2 ] && shift || shift 2

$command $* &
childpid=$!

sleep $timeout 

check_pid_name $command $childpid && {
        kill $childpid
        sleep 0.1
        check_pid_name $command $childpid && kill -9 $childpid
        echo "$command $* timed out"
}

As you can see, it's quite simple. You just have to start the desired command in the background, sleep for the timeout, and then kill the process if it's still running.

Yes, this script has a defect, all the commands will wait $timeout to run, but that's easy to solve. I'll post an improved (but slightly more complex) version in my next post.

Blog Logo

Fernando Ipar


Published

Image

Fernando Ipar

"Tell my wife I love her very much, she knows"

Back to Overview