jbe*_*rd4 5 unix bash signals child-process bash-trap
我正在编写一个bash脚本,它会产生许多后台进程.我想在进程终止时收到通知; 我想知道终止过程的pid.
我已经看过使用wait,这样每个衍生进程的pid都被捕获并存储在一个数组中,然后遍历数组,并在每个进程上调用wait.这里以各种方式描述了这种技术:
如果我理解正确的话,问题在于,如果您希望在单个进程终止后立即执行某些操作,则效率相对较低.例如,如果您生成进程A和B,并且B在A之前完成,则执行必须等待A和B完成.B完成后我需要立即执行操作.
trap SIGCHLD当孩子终止时,似乎是立即执行操作的方法,但问题是我找不到确定SIGCHLD信号源的pid的方法,这也是我需要的.我发现的最接近的一个例子就是这篇文章中的第三个代码示例:
http://www.linuxforums.org/forum/programming-scripting/103996-multithreading-bash.html#post510187
为方便起见,我在这里复制粘贴:
#!/bin/bash
iNext=0
function ChildReturned() {
wait $1
echo "$1 was returned. Its exits status was: $?"
iNext=$((iNext+1))
StartChild $iNext
}
function StartChild {
./child $1 &
pid=$!
echo "Started: $1 PID= $pid"
trap 'ChildReturned $pid' SIGCHLD
}
set -bm
for (( iNext=0; iNext<=10; iNext++ ));
do
StartChild $iNext
done
wait
Run Code Online (Sandbox Code Playgroud)
我认为这个例子不起作用,因为作者犯了trap多次调用的错误,每次都在trap's参数中捕获一个不同的pid变量.每次调用陷阱时,它都会覆盖先前的调用,因此将捕获任意pid.我找不到更好的技术.
有没有办法在bash中使用陷阱获取已终止子进程的pid?
更新
我只想指出这个资源,其中包含迄今为止我所看到的解决此问题的最佳,最全面的概述:
设置陷阱一次,在陷阱中你可以调用jobs -n以查看自上次检查以来哪些孩子已经完成。请注意,这并不能告诉您哪个孩子发送了 SIGCHLD;而是告诉您哪个孩子发送了 SIGCHLD。考虑一下在你进入陷阱之前有两个孩子死去的情况。在这种情况下,你只会进入陷阱一次,而你实际上对哪个孩子的信号做出反应是一个有争议的问题。请注意,这-n是一个 bash 扩展,您可能更喜欢使用jobs -l.