Greg の Wikiと irc.freenode.net の #bash の助けに基づいて、私が思いついた方法を次に示します。
#!/bin/bash
trap 'rm -f manager; kill 0' EXIT
mkfifo manager
declare -A pids
restart () {
# assuming your servers/daemons are programs "a" and "b"
[[ -n ${pids[a]} ]] && kill "${pids[a]}"
[[ -n ${pids[b]} ]] && kill "${pids[b]}"
run_and_tell manager a & pids[a]=$!
run_and_tell manager b & pids[b]=$!
}
restart
while :; do
read < manager
restart
done
および run_and_tell:
#!/bin/bash
trap 'kill $pid' EXIT
manager=$1
prog=$2
$prog & pid=$!
wait $pid
echo >"$manager"
bash 4.3 バージョンほど良くはありませんが、動作するようです (たとえば、run_and_tell で「sleep 9999」を使用してテストします)。1 つの煩わしさはtrap 'kill $pid' EXIT
、ランナーで実行する必要があることです。親が殺されたら確実に殺されるように、$prog でも同じことをしなければならないようです。
run_and_tell を独自のプロセス グループに配置することで、トラップを回避する代替バージョンを次に示します。
#!/bin/bash
# The trap now needs to kill all created process groups:
trap 'rm -f manager; kill 0; kill ${pids[a]} ${pids[b]}' EXIT
mkfifo manager
declare -A pids
restart () {
# assuming servers/daemons are programs "a" and "b":
[[ -n ${pids[a]} ]] && kill -TERM -"${pids[a]}"
[[ -n ${pids[b]} ]] && kill -TERM -"${pids[b]}"
setsid ./run_and_tell manager a & pids[a]=$!
setsid ./run_and_tell manager b & pids[b]=$!
}
restart
while :; do
read < manager
restart
done
run_and_tell は次のようになります。
#!/bin/bash
manager=$1
prog=$2
$prog
echo >"$manager"