1: #!/bin/ksh
2: # $Header: /afs/northstar/ufac/richard/projects/mcasey/run-with-timeout,v 1.5 2008/10/22 16:51:00 richard Exp $
3: #
4: # Run a command, but kill it if it has not returned after $timeout seconds
5: #
6: # Richard Brittain, 2008/07/05
7: #
8: # 1.1: tested on OSX 10.4 with ksh
9: #
10: # Make sure backgrounded processes are not auto-niced.
11: set +o bgnice
12:
13: timeout=$1; shift
14:
15: # signal handler to trap ALRM
16: function timeout_handler
17: {
18: # Other logging possible here.
19: echo "timeout after $timeout s: \"$command $args\": killed" >&2
20: # Kill the process which didn't complete as expected
21: # If $proc isn't set, we got called too soon.
22: [[ -n "$proc" ]] && kill -s TERM $proc
23: # Set an exit status to be returned to indicate timeout
24: estatus=127
25: }
26:
27: # Get the command and arguments to be run
28: command=$1; shift
29: args="$@"
30:
31: # Set trap on SIGALRM
32: trap timeout_handler ALRM
33:
34: # Now start the alarm timer
35: # Arrange to interrupt ourselves after some timeout
36: # $pid is PID of this shell
37: pid=$$
38: (
39: # Sleep for $timeout seconds. If we haven't been killed, send a SIGALRM to our caller
40: sleep $timeout
41: kill -s ALRM $pid
42: ) &
43: # $alarm is the PID of the alarm subshell itself
44: alarm=$!
45:
46: # Run the command in background and get the PID in $proc so we can kill it if needed
47: # Using 'eval' allows us to process shell redirection and other metacharacters, but breaks
48: # quoting for any argument with embedded spaces.
49: # Don't allow shell metacharacters as actual arguments. This probably won't work if the command is a pipeline
50: ## eval "$command" "$args" \&
51: $command "$@" &
52: proc=$!
53: # Now wait for the command to complete. Generally this is what will be interrupted if it times out
54: wait $proc
55: pstatus=$?
56: # The process exit status is captured in $pstatus, if it completed.
57: # Kill the alarm process, if it is still running (don't bother testing)
58: kill -s TERM $alarm 2>/dev/null
59: # echo "Exiting with status ${estatus:-$pstatus}" >&2
60: exit ${estatus:-$pstatus}
| last modified 02/04/2009 | Introduction | Table of Contents (frame/no frame) |
Printable (single file) |
© Dartmouth College |