Commit 1e0d4044 authored by Tommi's avatar Tommi

initial commit

parents
# keepalive.sh
keepalive.sh is yet another script that unconditionally attempts to keep a
process alive.
## Quick start
```sh
% sh keepalive.sh command
```
This will launch `command` and restart it should it exit.
## Getting started
### Source
keepalive.sh is hosted at GitLab, https://gitlab.com/tsaviran/keepalive .
### Dependencies
* Any Bourne shell
* Standard Unix tools: tr, head, sed, expr, sleep
## Usage
```
Usage: keepalive.sh ARG ...
env can be
FORK=y fork process
BACKOFF_INIT=2 initial backoff time in seconds
BACKOFF_MULTI=2.0 multiply backoff with f on failure
BACKOFF_RAND=1.0 multiplier for backoff randomness
BACKOFF_LIMIT=300 backoff time upper limit in seconds
BACKOFF_MIN=2 minimum backoff time in seconds
LIFE_EXPECTANCY=15 expected life time of a process in seconds
DEBUG= enable debugging
```
### Examples
```sh
% FORK=y sh keepalive.sh autossh tunnel -N
```
While autossh is an excellent tool, it exits on 0 return code. keepalive.sh can
be used to address this feature.
#! /bin/sh
set -e
usage() {
cat <<USAGE
Usage: $0 ARG ...
env can be
FORK=y fork process
BACKOFF_INIT=2 initial backoff time in seconds
BACKOFF_MULTI=2.0 multiply backoff with f on failure
BACKOFF_RAND=1.0 multiplier for backoff randomness
BACKOFF_LIMIT=180 backoff time upper limit in seconds
BACKOFF_MIN=2 minimum backoff time in seconds
LIFE_EXPECTANCY=15 expected life time of a process in seconds
DEBUG= enable debugging
USAGE
}
debug() {
test "$DEBUG" || return 0
echo "$@" >&2
}
rand_m() {
tr -cd 0-9 </dev/urandom | head -c3 | sed 's/^0*//'
}
to_milli() {
echo $1 | sed '
# init counter
x
s/^/123/
x
:l
x
/./ ! { x; b p } # done shifting
s/.//
x
/\../ { s/\.\(.\)/\1./; b l } # shift separator, then repeat
/\./ { s/\.$/0/; b l } # or replace separator, then repeat
s/$/0/ # or just add zeros
b l # then repeat
:p
s/\..*//
'
}
if test $# -eq 0; then
usage
exit 0
fi
if test "$FORK"; then
unset FORK
export FORK
sleep 1 # prevent a fork bomb :-/
sh "$0" "$@" &
exit 0
fi
# set defaults
test "$BACKOFF_INIT" || BACKOFF_INIT=5
test "$BACKOFF_MULTI" || BACKOFF_MULTI=1.0
test "$BACKOFF_RAND" || BACKOFF_RAND=1.0
test "$BACKOFF_LIMIT" || BACKOFF_LIMIT=180
test "$LIFE_EXPECTANCY" || LIFE_EXPECTANCY=15
BACKOFF_MULTI="$(to_milli $BACKOFF_MULTI)"
BACKOFF_RAND="$(to_milli $BACKOFF_RAND)"
debug "init: $BACKOFF_INIT"
debug "multi: $BACKOFF_MULTI"
debug "rand: $BACKOFF_RAND"
debug "init: $BACKOFF_LIMIT"
debug "life: $LIFE_EXPECTANCY"
backoff=$BACKOFF_INIT
while true; do
started_at="$(date +%s)"
"$@"
alive="$(expr $(date +%s) - $started_at)" || true
debug "process life: $alive, expected $LIFE_EXPECTANCY"
if test $alive -ge $LIFE_EXPECTANCY; then
backoff=$BACKOFF_INIT
sleep $backoff
continue
fi
backoff="$(expr $backoff + $backoff \* $BACKOFF_MULTI \* \
$(rand_m) / 1000000)"
test $backoff -ge $BACKOFF_INIT || backoff=$BACKOFF_INIT
if test $backoff -gt $BACKOFF_LIMIT; then
extra="$(expr $backoff - $BACKOFF_LIMIT)"
debug "Throttle backoff. Sleep additional $extra"
sleep $extra
backoff=$BACKOFF_LIMIT
fi
debug "Backoff $backoff seconds"
sleep $backoff
done
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment