i-bash/examples/scripts/timeout3

93 lines
2.5 KiB
Text
Raw Normal View History

2009-01-12 13:36:28 +00:00
#!/bin/bash
#
# The Bash script executes a command with a time-out.
# Based on the Bash documentation example.
#
# Upon time-out expiration SIGTERM (15) is sent to the process. If the signal
2009-01-12 13:36:28 +00:00
# is blocked, then the subsequent SIGKILL (9) terminates it.
# Dmitry V Golovashkin (E-mail: dvg@ieee.org)
2009-01-12 13:36:28 +00:00
#
script_name="${0##*/}"
2009-01-12 13:36:28 +00:00
# Default values.
readonly param_timeout=5
readonly param_interval=1
readonly param_delay=1
2009-01-12 13:36:28 +00:00
declare -i timeout=param_timeout
declare -i interval=param_interval
declare -i delay=param_delay
2009-01-12 13:36:28 +00:00
blue="$(tput setaf 4)"
bold_red="$(tput bold; tput setaf 1)"
off="$(tput sgr0)"
2009-01-12 13:36:28 +00:00
function print_usage() {
cat <<EOF
2009-01-12 13:36:28 +00:00
Synopsis: $script_name [-t timeout] [-i interval] [-d delay] command
2009-01-12 13:36:28 +00:00
Executes the command with a time-out. Upon time-out expiration SIGTERM (15) is
sent to the process. If SIGTERM signal is blocked, then the subsequent SIGKILL
(9) terminates it.
2009-01-12 13:36:28 +00:00
$blue-t timeout$off
Number of seconds to wait for command completion.
Default value: $param_timeout seconds. In some practical situations
this value ${bold_red}must$off be increased (for instance -t 180) to allow
the command to complete.
2009-01-12 13:36:28 +00:00
$blue-i interval$off
Interval between checks if the process is still alive.
Positive integer, default value: $param_interval seconds.
Default value is OK for most situations.
2009-01-12 13:36:28 +00:00
$blue-d delay$off
Delay between posting the SIGTERM signal and destroying the process by
SIGKILL. Default value: $param_delay seconds.
Default value is OK for most situations.
2009-01-12 13:36:28 +00:00
As of today, Bash does not support floating point arithmetic (sleep does),
therefore all time values must be integers.
Dmitry Golovashkin (E-mail: dvg@ieee.org)
2009-01-12 13:36:28 +00:00
EOF
exit 1 # No useful work was done.
2009-01-12 13:36:28 +00:00
}
# Options.
while getopts ":t:i:d:" option; do
case "$option" in
t) timeout=$OPTARG ;;
i) interval=$OPTARG ;;
d) delay=$OPTARG ;;
*) print_usage ;;
2009-01-12 13:36:28 +00:00
esac
done
shift $((OPTIND - 1))
# $# should be at least 1 (the command to execute), however it may be strictly
# greater than 1 if the command itself has options.
if (($# == 0 || interval <= 0)); then
print_usage
2009-01-12 13:36:28 +00:00
fi
# kill -0 pid Exit code indicates if a signal may be sent to "pid" process.
2009-01-12 13:36:28 +00:00
(
((t = timeout))
while ((t > 0)); do
sleep $interval
kill -0 $$ || exit 0
((t -= interval))
done
# Be nice, post SIGTERM first.
# The 'exit 0' below will be executed if any preceeding command fails.
kill -s SIGTERM $$ && kill -0 $$ || exit 0
sleep $delay
kill -s SIGKILL $$
) 2> /dev/null &
exec "$@"