Add the time-out script
License: MIT Signed-off-by: Jakub Sztandera <kubuxu@protonmail.ch>
Jakub Sztandera committed
Jun 8, 2016 at 12:22 UTC
4190076c6673fdd8d186c5fcfa2420ae7686ae6d
2 files changed
+92
test/bin/.gitignore
+1
@@ -8,3 +8,4 @@
8
!checkflags
9
!continueyn
10
!verify-go-fmt.sh
11
+!time-out
test/bin/time-out
new
+91
@@ -0,0 +1,91 @@
1
+#!/bin/bash
2
+#
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.
6
+#
7
+# Based on the Bash documentation example.
8
+
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.
14
+#
15
+# Dmitry V Golovashkin <Dmitry.Golovashkin@sas.com>
16
+
17
+scriptName="${0##*/}"
18
+
19
+declare -i DEFAULT_TIMEOUT=9
20
+declare -i DEFAULT_INTERVAL=1
21
+declare -i DEFAULT_DELAY=1
22
+
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
29
+
30
+function printUsage() {
31
+ cat <<EOF
32
+
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.
38
+
39
+ -t timeout
40
+ Number of seconds to wait for command completion.
41
+ Default value: $DEFAULT_TIMEOUT seconds.
42
+
43
+ -i interval
44
+ Interval between checks if the process is still alive.
45
+ Positive integer, default value: $DEFAULT_INTERVAL seconds.
46
+
47
+ -d delay
48
+ Delay between posting the SIGTERM signal and destroying the
49
+ process by SIGKILL. Default value: $DEFAULT_DELAY seconds.
50
+
51
+As of today, Bash does not support floating point arithmetic (sleep does),
52
+therefore all delay/time values must be integers.
53
+EOF
54
+}
55
+
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))
66
+
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
72
+fi
73
+
74
+# kill -0 pid Exit code indicates if a signal may be sent to $pid process.
75
+(
76
+ ((t = timeout))
77
+
78
+ while ((t > 0)); do
79
+ sleep $interval
80
+ kill -0 $$ || exit 0
81
+ ((t -= interval))
82
+ done
83
+
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 &
90
+
91
+exec "$@"