我在我的脚本中运行了几个后台进程
run_gui()
{
exec ... # the real commands here
}
函数run_ai1(), run_ai2
是类似的。
然后我运行这些功能并进行所需的管道
run_gui &
run_ai1 &
run_ai2 &
while true; do
while true; do
read -u $ai1_outfd line || echo "Nothing read"
if [[ $line ]]; then
: # processing
fi
done
sleep $turndelay
while true; do
read -u $ai2_outfd line || echo "nothing read"
if [[ $line ]]; then
: # processing
fi
done
sleep $turndelay
done
如果这三个进程中的任何一个退出,我想检查它们的退出代码并终止其余的进程。例如,如果run_ai2
以退出代码3退出,那么我想停止进程run_ai1
和run_gui
并退出主脚本,退出代码为1.不同背景的正确exitcodes流程可能有所不同。
问题是:我该如何检测它?有wait
命令,但我事先并不知道哪个脚本会先完成。我可以运行wait
作为后台流程 - 但它变得更加笨拙。
你能帮我吗?
答案 0 :(得分:2)
以下脚本监视测试子进程(在示例中,sleep + false和sleep + true)并报告其PID和退出代码:
#!/bin/bash
set -m
trap myhandler CHLD
myhandler() {
echo sigchld received
cat /tmp/foo
}
( sleep 5; false; echo "exit p1=$?" ) > /tmp/foo &
p1=$!
echo "p1=$p1"
( sleep 3; true; echo "exit p2=$?" ) > /tmp/foo &
p2=$!
echo "p2=$p2"
pstree -p $$
wait
结果是:
p1=3197
p2=3198
prueba(3196)─┬─prueba(3197)───sleep(3199)
├─prueba(3198)───sleep(3201)
└─pstree(3200)
sigchld received
sigchld received
exit p2=0
sigchld received
exit p1=1
使用SIGUSR1
代替SIGCHLD
可能会很有趣;请看这里的示例:https://stackoverflow.com/a/12751700/4886927。
此外,在陷阱处理程序内部,可以验证哪个孩子还活着。类似的东西:
myhandler() {
if kill -0 $p1; then
echo "child1 is alive"
fi
if kill -0 $p2; then
echo "child2 is alive"
fi
}
当其中一个孩子去世时,或杀死两个孩子:
myhandler() {
if kill -0 $p1 && kill -0 $p2; then
echo "all childs alive"
else
kill -9 $p1 $p2
fi
}