Patch-ID: bash40-021
[bash.git] / examples / scripts / timeout3
blob5c19d2ec9fb1070ee9ddaf5a7af19d83acf64297
1 #!/bin/bash
3 # The Bash shell script executes a command with a time-out.
4 # Upon time-out expiration SIGTERM (15) is sent to the process. If the signal
5 # is blocked, then the subsequent SIGKILL (9) terminates it.
7 # Based on the Bash documentation example.
9 # Hello Chet,
10 # please find attached a "little easier" :-) to comprehend
11 # time-out example. If you find it suitable, feel free to include
12 # anywhere: the very same logic as in the original examples/scripts, a
13 # little more transparent implementation to my taste.
15 # Dmitry V Golovashkin <Dmitry.Golovashkin@sas.com>
17 scriptName="${0##*/}"
19 declare -i DEFAULT_TIMEOUT=9
20 declare -i DEFAULT_INTERVAL=1
21 declare -i DEFAULT_DELAY=1
23 # Timeout.
24 declare -i timeout=DEFAULT_TIMEOUT
25 # Interval between checks if the process is still alive.
26 declare -i interval=DEFAULT_INTERVAL
27 # Delay between posting the SIGTERM signal and destroying the process by SIGKILL.
28 declare -i delay=DEFAULT_DELAY
30 function printUsage() {
31 cat <<EOF
33 Synopsis
34 $scriptName [-t timeout] [-i interval] [-d delay] command
35 Execute a command with a time-out.
36 Upon time-out expiration SIGTERM (15) is sent to the process. If SIGTERM
37 signal is blocked, then the subsequent SIGKILL (9) terminates it.
39 -t timeout
40 Number of seconds to wait for command completion.
41 Default value: $DEFAULT_TIMEOUT seconds.
43 -i interval
44 Interval between checks if the process is still alive.
45 Positive integer, default value: $DEFAULT_INTERVAL seconds.
47 -d delay
48 Delay between posting the SIGTERM signal and destroying the
49 process by SIGKILL. Default value: $DEFAULT_DELAY seconds.
51 As of today, Bash does not support floating point arithmetic (sleep does),
52 therefore all delay/time values must be integers.
53 EOF
56 # Options.
57 while getopts ":t:i:d:" option; do
58 case "$option" in
59 t) timeout=$OPTARG ;;
60 i) interval=$OPTARG ;;
61 d) delay=$OPTARG ;;
62 *) printUsage; exit 1 ;;
63 esac
64 done
65 shift $((OPTIND - 1))
67 # $# should be at least 1 (the command to execute), however it may be strictly
68 # greater than 1 if the command itself has options.
69 if (($# == 0 || interval <= 0)); then
70 printUsage
71 exit 1
74 # kill -0 pid Exit code indicates if a signal may be sent to $pid process.
76 ((t = timeout))
78 while ((t > 0)); do
79 sleep $interval
80 kill -0 $$ || exit 0
81 ((t -= interval))
82 done
84 # Be nice, post SIGTERM first.
85 # The 'exit 0' below will be executed if any preceeding command fails.
86 kill -s SIGTERM $$ && kill -0 $$ || exit 0
87 sleep $delay
88 kill -s SIGKILL $$
89 ) 2> /dev/null &
91 exec "$@"