Skip to content

Instantly share code, notes, and snippets.

@s1037989
Last active November 7, 2020 04:07
Show Gist options
  • Save s1037989/53ad6513eef6cf8232d734697f8c19d8 to your computer and use it in GitHub Desktop.
Save s1037989/53ad6513eef6cf8232d734697f8c19d8 to your computer and use it in GitHub Desktop.
Bash manage child processes
#!/usr/bin/env bash
cleanup() {
flock unlock
exit
}
die() {
echo "$*"
exit
}
kill() {
[[ -z "$1" ]] && return 1
[[ $1 -gt 0 ]] && builtin kill $1 >/dev/null 2>&1 && echo "killed $1" 1>&2
}
poke() {
[[ -z "$1" ]] && return 1
builtin kill -0 $1 >/dev/null 2>&1
}
sleep() {
local IFS
[[ -n "${_snore_fd:-}" ]] || exec {_snore_fd}<> <(:)
read ${1:+-t "$1"} -u $_snore_fd || :
}
tail1() {
if [[ ${tail1pid:-0} -eq 0 ]] || ! poke $tail1pid; then
[[ $(((last_tail1=$(date +%s))-${last_tail1:-0})) -le 1 ]] && die "restarting tail1 too fast"
tail -n 0 -f --pid=$$ ${logfile:-/var/log/messages} >/dev/null &
tail1pid=$!
echo "Started $tail1pid: tail1 -n 0 -f --pid=$$"
else
[[ -z "$last_tail1" ]] && echo "Already started $tail1pid"
last_tail1=0
fi
}
tail2() {
if [[ ${tail2pid:-0} -eq 0 ]] || ! poke $tail2pid; then
[[ $(((last_tail2=$(date +%s))-${last_tail2:-0})) -le 1 ]] && die "restarting tail2 too fast"
tailfile -n 0 -f --pid=$$ ${logfile:-/var/log/messages} >/dev/null &
tail2pid=$!
echo "Started $tail2pid: tail2 -n 0 -f --pid=$$"
else
[[ -z "$last_tail2" ]] && echo "Already started $tail2pid"
last_tail2=0
fi
}
tail3() {
if [[ ${tail3pid:-0} -eq 0 ]] || ! poke $tail3pid; then
[[ $(((last_tail3=$(date +%s))-${last_tail3:-0})) -le 1 ]] && die "restarting tail3 too fast"
tailfile -n 0 -f --pid=$$ ${logfile:-/var/log/messages} >/dev/null &
tail3pid=$!
echo "Started $tail3pid: tail3 -n 0 -f --pid=$$"
else
[[ -z "$last_tail3" ]] && echo "Already started $tail3pid"
last_tail3=0
fi
}
_tail() {
[[ "$*" =~ --pid=([0-9]+) ]]
local ppid=${BASH_REMATCH[1]}
echo "${0##*/} tailing $logfile" 1>&2
while poke $ppid; do
[[ -n "$P" ]] && echo -n "$P" 1>&2
sleep .1
done
}
flock() {
local tmp=${TMP:-/tmp}
local lockfile=$tmp/.${0##*/}
case "$1" in
lock)
trap - 0
[[ -z "$last_restart" && -f $lockfile ]] && die "$lockfile locked" || touch $lockfile
trap cleanup 0
;;
unlock)
rm -fv $lockfile
;;
esac
trap cleanup 0 2 3 15
}
main() {
while :; do
tail1
tail2
tail3
if [[ -z "$TERM" ]]; then
sleep .1
else
read -s -t .1 -n1 -p "$p" key
case "$key" in
1) kill $tail1pid;;
2) kill $tail2pid;;
3) kill $tail3pid;;
p) echo "-- -1 $tail1pid -2 $tail2pid -3 $tail3pid"; ps $tail1pid $tail2pid $tail3pid; pstree -acp $$;;
q) break;;
esac
fi
done
}
echo "Starting $0 $@ ($$)"
case "${0##*/}" in
tailfile) _tail "$@"; exit;;
esac
# Process non-hidden args normally
while getopts 'a:b:c:' o; do
case "$o" in
*) true;;
esac
done
shift $(($OPTIND-1))
logfile=$1; shift
export logfile
# And now business as usual...
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment