I wanted to keep some programs running, which is to say restart them if they crashed, but I also wanted them to be able to exit normally. The platform is Linux, the problem is compiz, the solution is a very small shell script. Surely the internets will let me know if there is something grossly wrong with it. This script is not meant for long-running daemons, there are plenty of tools for that already.
Here 'tis:
#!/bin/bash
#
# keeprunning - keep a process running unless it flaps
# exits with the status of the child process
# lets it exit if it wants to
#
declare -i STARTTIME TIME
if [ "x${1}x" == "x-fx" ]; then
shift
if [ ! -z "${1##*[!0-9]*}" ]; then
FLAPTIME=$1
shift
else
echo "-f expects an integer for flap time in seconds"
exit 1
fi
fi
if [ "$#" == "0" ]; then
echo "keeprunning - keep a process running unless it flaps
usage: keeprunning [-f seconds] <command>"
exit 1
fi
while true; do
STARTTIME=$(date +%s)
$*
exitstatus=$?
if [ "$exitstatus" -eq 0 ]; then
exit 0
else
TIME=${STARTTIME}+${FLAPTIME}
if [ $TIME -gt $(date +%s) ];
then
exit $exitstatus
else
echo "Restarting command \"$*\""
fi
fi
done
Credit to jilles for how to test for a number with shell builtins. This is actually a sh script, not really a bash script at all. In short, if the command exits with a non-zero status and after more than $FLAPTIME, it is restarted. If it exits with a zero status then it is assumed to have wanted to exit, and if it exits with a non-zero status but within $FLAPTIME, it is assumed to have crashed after a very short period and thusly deserved to have crashed, preventing restart loops. Relaunching also/only on zero status would be an obvious improvement to this script. So would permitting a specified number of restart attempts rather than just giving up.