0

Greg の Wikiには、サーバーが終了した場合に st を実行し続ける方法の非常に簡単な例があり、すぐに再起動されます。

#!/bin/sh
while :; do
   /my/game/server -foo -bar -baz >> /var/log/mygameserver 2>&1
done

しかし、N 台のサーバーを実行し続けたい場合はどうでしょうか。http://wiki.bash-hackers.org/scripting/bashchangesによると、bash 4.3 でできるようになります

while :; do
    server1 & p1=$!
    server2 & p2=$!
    wait -n $p1 $p2 # wait until at least one exits
    kill $p1 $p2
done

4.3 はまだアルファ版ですが、古いシステムでこれを行う方法はありますか?

4

2 に答える 2

0

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"
于 2013-09-13T09:59:17.693 に答える