如何在bash脚本中等待从该脚本派生的几个子进程完成,然后在任何子进程以code !=0结束时返回退出代码!=0?
简单的脚本:
#!/bin/bash
for i in `seq 0 9`; do
doCalculations $i &
done
wait
上面的脚本将等待所有10个子进程,但它总是给出退出状态0(参见help wait)。我如何修改这个脚本,以便它将发现衍生子进程的退出状态,并在任何子进程以code !=0结束时返回退出代码1 ?
有没有比收集子进程的pid、按顺序等待它们并求和退出状态更好的解决方案呢?
我刚刚修改了一个脚本到后台和并行化的过程。
我做了一些实验(在Solaris上使用bash和ksh),发现如果退出状态不为零,'wait'将输出退出状态,或者当没有提供PID参数时,将输出一个返回非零退出的作业列表。如。
Bash:
$ sleep 20 && exit 1 &
$ sleep 10 && exit 2 &
$ wait
[1]- Exit 2 sleep 20 && exit 2
[2]+ Exit 1 sleep 10 && exit 1
Ksh:
$ sleep 20 && exit 1 &
$ sleep 10 && exit 2 &
$ wait
[1]+ Done(2) sleep 20 && exit 2
[2]+ Done(1) sleep 10 && exit 1
这个输出被写入stderr,所以OPs示例的简单解决方案可以是:
#!/bin/bash
trap "rm -f /tmp/x.$$" EXIT
for i in `seq 0 9`; do
doCalculations $i &
done
wait 2> /tmp/x.$$
if [ `wc -l /tmp/x.$$` -gt 0 ] ; then
exit 1
fi
虽然这:
wait 2> >(wc -l)
也将返回一个计数,但不包含TMP文件。这也可以这样使用,例如:
wait 2> >(if [ `wc -l` -gt 0 ] ; then echo "ERROR"; fi)
但是这并不比tmp文件有用多少。我找不到一种有效的方法来避免tmp文件,同时也避免在子shell中运行“等待”,这根本不会起作用。