Path: utzoo!attcan!lsuc!sq!lee From: lee@sq.sq.com (Liam R. E. Quin) Newsgroups: comp.unix.questions Subject: Re: Timeout on shell command. Summary: arcane alternative approach entirely in the shell Message-ID: <1990Aug15.045649.26708@sq.sq.com> Date: 15 Aug 90 04:56:49 GMT References: <104854@convex.convex.com> Organization: SoftQuad Inc. Lines: 76 brister@decwrl.dec.com (James Brister) writes: >I'd like to have a shell script run a command, but if that command doesn't >finish in X seconds, then the script should kill it, if the command >finishes sooner then the script should immediately continue. tchrist@convex.COM (Tom Christiansen) writes: >Here's timeout.c; syntax is 'timeout seconds command'. That is probably the neatest solution. Another way (if you need a shell-only solution) is Process One: # write my PID ($$) to a tmp file, tmp1 echo $$ > $tmp1 # run command $command # mark ourselves as done: /bin/rm -f $tmp1 # if tmp2 exists, kill that process test -f $tmp2 && kill `cat $tmp2` Process Two: # write my PID to a file, tmp2 echo $$ > $tmp2 # wait a while sleep 27 # mark ourselves as done so the other half does not kill us now /bin/rm -f $tmp2 # kill the other half if it is still running test -f $tmp1 && kill `cat $tmp1` Now do ProcessOne & ProcessTwo & wait If you have other background tasks, write these three "lines" out to a temporary file and execute that -- then the wait will only wait for ProcessOne and ProcessTwo. If you don't want the PIDs to appear when you do the Process1 &, you can play tricks with /bin/sh -c "command &" which won't print the PID of the background process on most systems, but only works with simple commands (no |, &&, etc) without care. The variant ( /bin/sh -c "exec 2>&3; command" & ) 3>&2 2>/dev/null works better. It says, ^^^^ Run the thing in ( ) with file descriptor 3 open in addition to the standard 0, 1 and 2 (2 is standard error, used for messages). Make file descriptor 3 be the same as descriptor 2. Having done that, send everything written ^^^^^^^^^^^ on file descriptor 2 (standard error) to /dev/null -- in other words, throw away all error messages. This will throw away the PID, which is what we want, but will also throw away any error messages generated by "command". The exec 2>&3; tells the /bin/sh _inside_ the ( ) to make file descriptor 2 be the same as file descriptor 3, which we previously opened as the original standard error. So this restores standard error messages for the command inside the quotes. Which is what we need. Well, you might say that it would be less arcane to include the C program `timeout' given by Tom Christiansen, and to compile it on the fly, but in practice the commands are likely (I hope) to be simple, and the first form with /bin/sh -c "command" will probably work fine. Lee -- Liam R. E. Quin, lee@sq.com, {utai,utzoo}!sq!lee, SoftQuad Inc., Toronto