120

Possible Duplicate:
Bash script that kills a child process after a given timeout

Is there a way to write a shell script that would execute a certain command for 15 seconds, then kill the command?

I have tried sleep, wait and ping but maybe I am using them wrong.

codeforester
  • 39,467
  • 16
  • 112
  • 140
AlanF
  • 1,591
  • 3
  • 14
  • 20

2 Answers2

238

Use the timeout command:

timeout 15s command

Note: on some systems you need to install coreutils, on others it's missing or has different command line arguments. See an alternate solution posted by @ArjunShankar . Based on it you can encapsulate that boiler-plate code and create your own portable timeout script or small C app that does the same thing.

Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
  • 3
    not to mention that it will return instantly if the command finished earlier – Karoly Horvath Apr 19 '12 at 09:19
  • So for the command Im trying to kill after 15 secs I have tried using this command but it didnt stop the command from running, I have also tried using timeout - k 15 and that also didnt work :( – AlanF Apr 19 '12 at 09:41
  • this is how you **run** the command. – Karoly Horvath Apr 19 '12 at 09:46
  • 1
    Where does the `timeout` command come from? I don't have it on any of the RHEL or Ubuntu servers I'm on. (Or in FreeBSD or OS X, for that matter.) – ghoti Apr 19 '12 at 11:17
  • 1
    It's in coreutils 8.x on my debian box. – Graham Apr 19 '12 at 11:19
  • I have been reading about this, and I find that `timeout` is not the portable way to do this. There are two popular implementations of `timeout` with slightly different features. One is part of [TCT](http://www.porcupine.org/forensics/tct.html) and one part of [coreutils](http://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html). I have an obscure implementation on an RHEL machine I am on now (I don't maintain it so I don't know who installed this one), and it has a completely different set of flags (e.g. `-t` for setting the timeout). – ArjunShankar Apr 19 '12 at 12:27
  • @ArjunShankar: thx, I used it with debian, ubuntu, centos and cygwin, all working fine here. – Karoly Horvath Apr 19 '12 at 15:35
  • @KarolyHorvath - Right. I figure that it would only be an occasional machine that doesn't have the coreutils implementation installed. – ArjunShankar Apr 19 '12 at 15:43
  • 1
    Coreutils would be missing from anything that is FreeBSD, NetBSD, OS X, HP/UX, Solaris, AIX, etc. – Graham Apr 19 '12 at 22:32
  • 3
    With homebrew-installed `coreutils` on OS X, the command is available as `gtimeout` – joeln Nov 23 '16 at 04:13
  • this is good for a simple command timeout; however, for quoted arguments and multiple commands, quoting spaghetti begins, e.g. this obtuse example: `timeout 5s sh -c "while true; do echo \"\\\"quoted\\\"\"; sleep 1; done"` – Jack Wasey Jul 19 '21 at 07:17
66

Some machines don't have timeout installed/available. In that case, you could background the process; its PID then gets stored as $!; then sleep for the required amount of time, then kill it:

some_command arg1 arg2 &
TASK_PID=$!
sleep 15
kill $TASK_PID

At this URL I find that there are mentioned, more than one solutions to make this happen.

ArjunShankar
  • 23,020
  • 5
  • 61
  • 83
  • 6
    I initially deleted my answer (because, clearly, Karoly's is so much more awesome), but it appears that some people don't have `timeout` => undeleted. – ArjunShankar Apr 19 '12 at 11:24