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.
Related posts:
- Running commands from the shell with a timeout Sometimes, in a shell script, you need to run a...
- 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.











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.
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?