在后台启动程序,并在其中一个程序因退出代码而死亡时立即终止程序

时间:2012-04-06 00:52:34

标签: python bash shell subprocess kill

在Linux上,我想将一些服务器作为后台服务产生。

一旦其中一个以退出代码终止!= 0 ,他们全部将成为SIGTERMed,并且在3秒后,如果他们不在我想去。

按下Ctrl-C时也会发生同样的情况。

我想要一个粗略的等同于

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

(不幸的是,上面的代码具有所有提到的属性。)

儿童可以 来窃取/逃脱Ctrl-C信号。

我接受 Bash Python (使用subprocess)中的解决方案。对于Python,他们可能只使用标准库函数(我不需要首先使用pip下载模块)。如果你有一种很酷的方式用另一种语言来做这件事,请不要犹豫,不要表现出来。

如果它也适用于Mac OS,则可获得奖励。

3 个答案:

答案 0 :(得分:1)

我建议在哪里查看:setpgrpwaitpidkill,而不是为您编写解决方案。请注意“儿童不可能窃取/逃脱Ctrl-C信号。”既不可能(唯一不可避免的信号是SIGSTOPSIGKILL)也没有意义(你没有向他们提供SIGINT)。

您无法在bash中正确执行此操作,因为wait等待所有指定的(或者,如果没有指定,只是所有)进程;你需要“任何”语义,而不是“所有”。

答案 1 :(得分:0)

在技术上可以直接在bash中执行此操作,但我不会,因为它需要大量轮询并且效率低且容易出错(基本上你必须{{1测试进程是否仍然存在)。这里有一些bash代码(来自我周围的脚本),它显示了如何记录后台进程pid:

kill -0 $pid

并且在这种特殊情况下,您可能会使用“协同处理”和相当多的黑客攻击来使其更好地工作(比上述情况有意限制)。

在Python中会更容易,但不要使用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 } ;使用直接OS调用(如上所述的@geekosaur)。 @ jldupont对http://supervisord.org/的建议看起来很好(特别是因为它是用Python编写的)。

答案 2 :(得分: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