Ben's

bash timeout 래퍼 본문

리눅스/bash

bash timeout 래퍼

Ben Ko (SINCE 2013) 2013. 1. 17. 17:11
728x90

#!/bin/bash
 
##########################################################################
# Shellscript:  timeout - set timeout for a command
# Author     :  Heiner Steven <heiner.steven@odn.de>
# Date       :  29.07.1999
# Category   :  File Utilities
# Requires   :
# SCCS-Id.   :  @(#) timeout    1.3 03/03/18
##########################################################################
# Description
#    o  Runs a command, and terminates it (by sending a signal) after
#       a specified time period
#    o  This command first starts itself as a "watchdog" process in the
#       background, and then runs the specified command.
#       If the command did not terminate after the specified
#       number of seconds, the "watchdog" process will terminate
#       the command by sending a signal.
#
# Notes
#    o  Uses the internal command line argument "-p" to specify the
#       PID of the process to terminate after the timeout to the
#       "watchdog" process.
#    o  The "watchdog" process is invoked by the name "$0", so
#       "$0" must be a valid path to the script.
#    o  If this script runs in the environment of the login shell
#       (i.e. it was invoked using ". timeout command...") it will
#       terminate the login session.
##########################################################################
 
PN=`basename "$0"`                      # Program name
VER='1.3'
 
TIMEOUT=5                               # Default [seconds]
 
Usage () {
    echo >&2 "$PN - set timeout for a command, $VER
usage: $PN [-t timeout] command [argument ...]
     -t: timeout (in seconds, default is $TIMEOUT)"
    exit 1
}
 
Msg () {
    for MsgLine
    do echo "$PN: $MsgLine" >&2
    done
}
 
Fatal () { Msg "$@"; exit 1; }
 
while [ $# -gt 0 ]
do
    case "$1" in
        -p)     ParentPID=$2; shift;;   # Used internally!
        -t)     Timeout="$2"; shift;;
        --)     shift; break;;
        -h)     Usage;;
        -*)     Usage;;
        *)      break;;                 # First file name
    esac
    shift
done
 
: ${Timeout:=$TIMEOUT}                  # Set default [seconds]
 
if [ -z "$ParentPID" ]
then
    # This is the first invokation of this script.
    # Start "watchdog" process, and then run the command.
    [ $# -lt 1 ] && Fatal "please specify a command to execute"
    "$0" -p $$ -t $Timeout &            # Start watchdog
    #echo >&2 "DEBUG: process id is $$"
    exec "$@"                           # Run command
    exit 2                              # NOT REACHED
else
    # We run in "watchdog" mode, $ParentPID contains the PID
    # of the process we should terminate after $Timeout seconds.
    [ $# -ne 0 ] && Fatal "please do not use -p option interactively"
 
    #echo >&2 "DEBUG: $$: parent PID to terminate is $ParentPID"
 
    exec >/dev/null 0<&1 2>&1   # Suppress error messages
    sleep $Timeout
    kill $ParentPID &&                  # Give process time to terminate
        (sleep 2; kill -1 $ParentPID) &&
        (sleep 2; kill -9 $ParentPID)
    exit 0
fi

'리눅스 > bash' 카테고리의 다른 글

nl  (0) 2013.04.03
ext3 snapshot backup  (0) 2013.01.30
debian 한글 설정  (0) 2013.01.28
쉘 스크립트에서 글자 색 적용  (0) 2013.01.21
문자별로 필드 구분시키기  (0) 2013.01.21