这是我根据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”进行测试)。一个烦恼是我必须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"