Overdeath
Overdeath

Reputation: 695

Limiting the time a program runs in Linux

In Linux I would like to run a program but only for a limited time, like 1 second. If the program exceeds this running time I would like to kill the process and show an error message.

Upvotes: 50

Views: 30822

Answers (7)

falstro
falstro

Reputation: 35657

StackOverflow won't allow me to delete my answer since it's the accepted one. It's garnering down-votes since it's at the top of the list with a better solution below it. If you're on a GNU system, please use timeout instead as suggested by @wRAR. So in the hopes that you'll stop down-voting, here's how it works:

timeout 1s ./myProgram 

You can use s, m, h or d for seconds (the default if omitted), minutes, hours or days. A nifty feature here is that you may specify another option -k 30s (before the 1s above) in order to kill it with a SIGKILL after another 30 seconds, should it not respond to the original SIGTERM.

A very useful tool. Now scroll down and up-vote @wRAR's answer.


For posterity, this was my original - inferior - suggestion, it might still be if some use for someone.

A simple bash-script should be able to do that for you

./myProgram &
sleep 1
kill $! 2>/dev/null && echo "myProgram didn't finish"

That ought to do it.

$! expands to the last backgrounded process (through the use of &), and kill returns false if it didn't kill any process, so the echo is only executed if it actually killed something.

2>/dev/null redirects kill's stderr, otherwise it would print something telling you it was unable to kill the process.

You might want to add a -KILL or whichever signal you want to use to get rid of your process too.

EDIT
As ephemient pointed out, there's a race here if your program finishes and the some other process snatches the pid, it'll get killed instead. To reduce the probability of it happening, you could react to the SIGCHLD and not try to kill it if that happens. There's still chance to kill the wrong process, but it's very remote.

trapped=""
trap 'trapped=yes' SIGCHLD
./myProgram &
sleep 1
[ -z "$trapped" ] && kill $! 2>/dev/null && echo '...'

Upvotes: 68

tponthieux
tponthieux

Reputation: 1552

tail -f file & pid=$!
sleep 10
kill $pid 2>/dev/null && echo '...'

Upvotes: 1

wRAR
wRAR

Reputation: 25693

Ah well. timeout(1).

DESCRIPTION
Start COMMAND, and kill it if still running after DURATION.

Upvotes: 120

user231967
user231967

Reputation: 1975

Ok, so just write a short C program that forks, calls execlp or something similar in the child, measures the time in the parent and kills the child. Should be easy ...

Upvotes: 0

wRAR
wRAR

Reputation: 25693

Maybe CPU time limit (ulimit -t/setrlimit(RLIMIT_CPU)) will help?

Upvotes: 23

f4.
f4.

Reputation: 3852

you could launch it in a shell script using &

your_program &
pid=$!
sleep 1
if [ `pgrep $pid` ]
  then
    kill $pid
    echo "killed $pid because it took too long."
fi

hope you get the idea, I'm not sure this is correct my shell skills need some refresh :)

Upvotes: 3

user231967
user231967

Reputation: 1975

If you have the sources, you can fork() early in main() and then have the parent process measure the time and possibly kill the child process. Just use standard system calls fork(), waitpid(), kill(), ... maybe some standard Unix signal handling. Not too complicated but takes some effort.

You can also script something on the shell although I doubt it will be as accurate with respect to the time of 1 second.

If you just want to measure the time, type time <cmd ...> on the shell.

Upvotes: 0

Related Questions