如何在bash脚本中等待子进程,如果其中一个返回退出代码1,那么我想停止所有子进程。
这就是我想做的。但是有一些问题:
1.如果第一个进程比所有其他进程都长,并且另一个进程在后台失败...则脚本将等待第一个进程完成,即使另一个进程已经失败。
1.无法检测到doSomething失败,因为我使用管道作为所需的打印格式。
#!/bin/bash
function doSomething()
{
echo [ $1 start ]
sleep $1
if [ $1 == 10 ]; then
failed
fi
echo [ sleep $1 ]: done
}
function failed(){
sleep 2
echo ------ process failed ------
exit 1
}
function process_log() {
local NAME=$1
while read Line; do
echo [Name ${NAME}]: ${Line}
done
}
pids=""
(doSomething 4 | process_log 4)&
pids+="$! "
(doSomething 17 | process_log 17)&
pids+="$! "
(doSomething 6 | process_log 6)&
pids+="$! "
(doSomething 10 | process_log 10)&
pids+="$! "
(doSomething 22 | process_log 22)&
pids+="$! "
(doSomething 5 | process_log 5)&
pids+="$! "
for pid in $pids; do
wait $pid || (pkill -P $$ ; break)
done
echo done program
有人有主意吗?
2条答案
按热度按时间7z5jn7bk1#
它的要点是:
解释
其思想是让子进程在失败时通知父脚本(使用
SIGUSR1
信号);主脚本接着将在其接收到所述信号时杀死所有子进程。但有一个问题:删除子进程的PID可能还不够,例如,当它当前正在运行带有
|
的命令时。在这些情况下,您需要删除整个 * 进程组 *,这可以通过使用set -m
启用 * 作业控制 * 并在kill
命令中使用负PID来完成。zbdgwd5y2#
--halt-on-error now,1 --tag
**对于在每一行前面附加参数的特定
process_log
,GNU parallel可以用一行代码来完成。安装:
试验:
输出:
我们看到
4
和5
没有完成,因为3
在它们之前失败了,而且每一行都有输入参数作为前缀。GNU parallel还可以涵盖其他一些常见的前缀用例:
我的补充意见来自:如果任何函数并行失败,则停止bash也适用于此处。
在Ubuntu 22.04上测试。