]>
Commit | Line | Data |
---|---|---|
3185942a JA |
1 | #!/bin/bash |
2 | # | |
495aee44 CR |
3 | # The Bash script executes a command with a time-out. |
4 | # Based on the Bash documentation example. | |
5 | # | |
6 | # Upon time-out expiration SIGTERM (15) is sent to the process. If the signal | |
3185942a | 7 | # is blocked, then the subsequent SIGKILL (9) terminates it. |
495aee44 | 8 | # Dmitry V Golovashkin (E-mail: dvg@ieee.org) |
3185942a | 9 | # |
495aee44 | 10 | script_name="${0##*/}" |
3185942a | 11 | |
495aee44 CR |
12 | # Default values. |
13 | readonly param_timeout=5 | |
14 | readonly param_interval=1 | |
15 | readonly param_delay=1 | |
3185942a | 16 | |
495aee44 CR |
17 | declare -i timeout=param_timeout |
18 | declare -i interval=param_interval | |
19 | declare -i delay=param_delay | |
3185942a | 20 | |
495aee44 CR |
21 | blue="$(tput setaf 4)" |
22 | bold_red="$(tput bold; tput setaf 1)" | |
23 | off="$(tput sgr0)" | |
3185942a | 24 | |
495aee44 CR |
25 | function print_usage() { |
26 | cat <<EOF | |
3185942a | 27 | |
495aee44 | 28 | Synopsis: $script_name [-t timeout] [-i interval] [-d delay] command |
3185942a | 29 | |
495aee44 CR |
30 | Executes the command with a time-out. Upon time-out expiration SIGTERM (15) is |
31 | sent to the process. If SIGTERM signal is blocked, then the subsequent SIGKILL | |
32 | (9) terminates it. | |
3185942a | 33 | |
495aee44 CR |
34 | $blue-t timeout$off |
35 | Number of seconds to wait for command completion. | |
36 | Default value: $param_timeout seconds. In some practical situations | |
37 | this value ${bold_red}must$off be increased (for instance -t 180) to allow | |
38 | the command to complete. | |
3185942a | 39 | |
495aee44 CR |
40 | $blue-i interval$off |
41 | Interval between checks if the process is still alive. | |
42 | Positive integer, default value: $param_interval seconds. | |
43 | Default value is OK for most situations. | |
3185942a | 44 | |
495aee44 CR |
45 | $blue-d delay$off |
46 | Delay between posting the SIGTERM signal and destroying the process by | |
47 | SIGKILL. Default value: $param_delay seconds. | |
48 | Default value is OK for most situations. | |
3185942a JA |
49 | |
50 | As of today, Bash does not support floating point arithmetic (sleep does), | |
495aee44 CR |
51 | therefore all time values must be integers. |
52 | Dmitry Golovashkin (E-mail: dvg@ieee.org) | |
3185942a | 53 | EOF |
495aee44 | 54 | exit 1 # No useful work was done. |
3185942a JA |
55 | } |
56 | ||
57 | # Options. | |
58 | while getopts ":t:i:d:" option; do | |
59 | case "$option" in | |
60 | t) timeout=$OPTARG ;; | |
61 | i) interval=$OPTARG ;; | |
62 | d) delay=$OPTARG ;; | |
495aee44 | 63 | *) print_usage ;; |
3185942a JA |
64 | esac |
65 | done | |
66 | shift $((OPTIND - 1)) | |
67 | ||
68 | # $# should be at least 1 (the command to execute), however it may be strictly | |
69 | # greater than 1 if the command itself has options. | |
70 | if (($# == 0 || interval <= 0)); then | |
495aee44 | 71 | print_usage |
3185942a JA |
72 | fi |
73 | ||
495aee44 | 74 | # kill -0 pid Exit code indicates if a signal may be sent to "pid" process. |
3185942a JA |
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 "$@" | |
495aee44 | 92 |