By fernando | January 12, 2009

Running commands from the shell with a timeout (pt 2)

Here’s an improved version of the safecmd script. This one doesn’t always wait for $timeout seconds even if the command you’re running exits successfully. In that case, it kills the monitor script and ends at the proper time.

Here’s the code:

#!/bin/bash 

timeout=$1
command=$2
shift 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 "Usage: safecmd   [args]">&2 && exit 1

safe_run()
{
        command=$1
        shift
        $command $*
        kill $$
}

safe_run $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"
}

You can try it how like this, for example:

./safecmd 2 sleep 4

which will output

./safecmd.1: line 34: 11739 Terminated               safe_run $command $*
sleep 4 timed out
or ./safecmd 2 sleep 1

which will output

Terminated

Indicating that sleep 1 finished successfully

This is still missing something. You can’t test for the success of the command you pass safecmd, if it exits successfully you’ll see the same return code than if it would have exited with an error.

In order to improve this, as far as I can tell, you have to use two scripts, one just as the wrapper (to use one separate script instead of the function safe_run()). That’s the way this is handled in Highbase, and I’ll post a full example in my next post on this subject.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • MisterWong
  • Y!GG
  • Webnews
  • Digg
  • del.icio.us
  • StumbleUpon
  • Reddit
  • email
  • Facebook
  • LinkedIn
  • Technorati

Related posts:

  1. Running commands from the shell with a timeout Sometimes, in a shell script, you need to run a...
  2. Generating random salts from bash From the ‘just because it can be done’ column, here...

Related posts brought to you by Yet Another Related Posts Plugin.

2 comments | Add One

  1. Pádraig Brady - 01/13/2009 at 8:02 am

    Seems a bit complicated. Have a look at:
    http://www.pixelbeat.org/scripts/timeout

    Also note that there will be a timeout command included in newer versions of coreutils.

  2. fernando - 01/13/2009 at 12:08 pm

    Thanks for the reply. I had two similar replies in reddit, I guess I was really out of touch.

    I’ve just installed timeout through apt-get and it does just what my script from Highbase does, though I’ll wait until it’s included in coreutils to remove my self made version.

    I tried to figure out when timeout is coming with coreutils, and it seems you’re the contributor :) Any ideas for a date?

Leave a Comment

Name:

E-Mail :

Website :

Comments :