Example script: run-with-timeout.ksh


   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