2

Linux では、いくつかのサーバーをバックグラウンド サービスとして生成したいと考えています。

それらの 1 つが終了コード != 0 で終了するとすぐに、それらはすべてSIGTERM され、行きたくない場合は 3 秒の猶予期間後に KILL されます。

Ctrl-C が押されたときも同じことが起こります。

おおまかに相当するものが欲しい

set -e
server1 &
server2 &
server3 &
wait (+ kill on error)

(残念ながら、上記のコードには、前述のすべてのプロパティが含まれているわけではありません。)

子供が Ctrl-C シグナルを盗んだりエスケープしたりすることはできません。

BashおよびPythonでのソリューションを受け入れます(を使用subprocess)。Python の場合、標準ライブラリ関数のみを使用できます (最初にモジュールをダウンロードする必要はありませんpip)。これを別の言語で行うクールな方法がある場合は、遠慮なくそれを示してください。

Mac OSでも動作する場合はボーナスポイント。

4

3 に答える 3

1

あなたのために解決策を書くのではなく、どこを見るべきかを提案します: setpgrp, waitpid, kill. 「子供が Ctrl-C シグナルを盗んだりエスケープしたりすることはできない」ことに注意してください。可能ではありません (回避できない唯一の信号はSIGSTOPSIGKILLです) 意味もありません (あなたはそれらに配信SIGINTしていません)。

指定されたすべてのプロセス (または、何も指定されていない場合は単にすべてのプロセス) を待機するbashため、これを適切に行うことはできません。wait「すべて」ではなく「任意」のセマンティクスが必要です。

于 2012-04-06T01:11:25.937 に答える
0

これを bash で直接行うこと技術的には可能ですが、多くのポーリングが必要であり、非効率的でエラーが発生しやすいため、私はそうしません (基本的にkill -0 $pid、プロセスがまだ存在するかどうかをテストする必要があります)。バックグラウンド プロセスの pid を記録する方法を示す bash コード (私が横たわっているスクリプトから) を次に示します。

start_tail() {
    if [ x$TAIL_PID != x ]; then
        echo "internal error: already running tail (pid $TAIL_PID)"
    fi
    tail -0f $1 &
    TAIL_PID=$!
    trap "kill $TAIL_PID" 0 1 2 3 15
}

stop_tail() {
    if [ x$TAIL_PID != x ]; then
        kill $TAIL_PID; trap 0 1 2 3 15
        TAIL_PID=""
    fi
}

この特定のケースでは、「コプロセス」とかなりのハッキングを使用して、(意図的に制限されている上記よりも) うまく機能させることができます。

subprocessPython の方が簡単ですが、 ;は使用しないでください。直接 OS 呼び出しを使用します (上記の @geekosaur のように)。http://supervisord.org/に対する @jldupont の推奨事項は適切に見えます (特に Python で記述されているため)。

于 2012-04-06T08:10:36.387 に答える
0
#!/bin/sh
# Avoid <() process substitutions for portability's sake
set -bm
trap clean SIGCHLD
trap 'kill 0' SIGINT
trap 'sleep 3; kill -9 0' SIGTERM

clean() {
        while read spec pid extra; do
                wait $pid || kill 0
        done << EOF
                $( jobs -l | grep 'Exit\|Done' )
EOF
}

server1 &
server2 &
server3 &
wait
于 2012-04-06T14:18:58.617 に答える