#!/bin/sh # Minimal foreground supervisor for init systems without native Restart=. set -u restart=on-failure delay=5 workdir=/ logfile="" usage() { echo "usage: $0 [--restart always|on-failure|never] [--delay SEC] [--chdir DIR] [--log FILE] -- command [args...]" >&2 exit 64 } while [ "$#" -gt 0 ]; do case "$1" in --restart) [ "$#" -ge 2 ] || usage restart=$2 shift 2 ;; --delay) [ "$#" -ge 2 ] || usage delay=$2 shift 2 ;; --chdir) [ "$#" -ge 2 ] || usage workdir=$2 shift 2 ;; --log) [ "$#" -ge 2 ] || usage logfile=$2 shift 2 ;; --) shift break ;; *) usage ;; esac done [ "$#" -gt 0 ] || usage case "$restart" in always|on-failure|never) ;; *) usage ;; esac case "$delay" in ""|*[!0-9]*) usage ;; esac [ -d "$workdir" ] || mkdir -p "$workdir" 2>/dev/null || exit 73 if [ -n "$logfile" ]; then logdir=$(dirname "$logfile") [ -d "$logdir" ] || mkdir -p "$logdir" 2>/dev/null || exit 73 fi stopping=0 child="" forward_term() { stopping=1 if [ -n "$child" ]; then target=$child kill -TERM "$target" 2>/dev/null || true count=0 while kill -0 "$target" 2>/dev/null && [ "$count" -lt 30 ]; do sleep 0.1 count=$((count + 1)) done kill -KILL "$target" 2>/dev/null || true fi } forward_hup() { if [ -n "$child" ]; then kill -HUP "$child" 2>/dev/null || true fi } trap forward_term INT TERM trap forward_hup HUP while [ "$stopping" -eq 0 ]; do ( cd "$workdir" || exit 73 if [ -n "$logfile" ]; then exec "$@" >>"$logfile" 2>&1 fi exec "$@" ) & child=$! wait "$child" status=$? child="" [ "$stopping" -eq 0 ] || exit 0 case "$restart" in never) exit "$status" ;; on-failure) [ "$status" -ne 0 ] || exit 0 ;; always) ;; esac [ "$delay" -eq 0 ] || { sleep "$delay" & child=$! wait "$child" 2>/dev/null || true child="" } done exit 0