在Linux上,我想将一些服务器作为后台服务产生。
一旦其中一个以退出代码终止!= 0 ,他们全部将成为SIGTERMed,并且在3秒后,如果他们不在我想去。
按下Ctrl-C时也会发生同样的情况。
我想要一个粗略的等同于
set -e
server1 &
server2 &
server3 &
wait (+ kill on error)
(不幸的是,上面的代码不具有所有提到的属性。)
儿童可以 来窃取/逃脱Ctrl-C信号。
我接受 Bash 和 Python (使用subprocess
)中的解决方案。对于Python,他们可能只使用标准库函数(我不需要首先使用pip
下载模块)。如果你有一种很酷的方式用另一种语言来做这件事,请不要犹豫,不要表现出来。
如果它也适用于Mac OS,则可获得奖励。
答案 0 :(得分:1)
我建议在哪里查看:setpgrp
,waitpid
,kill
,而不是为您编写解决方案。请注意“儿童不可能窃取/逃脱Ctrl-C信号。”既不可能(唯一不可避免的信号是SIGSTOP
和SIGKILL
)也没有意义(你没有向他们提供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