是否可以在后台运行多个命令但是等待所有结果并在命令失败时使脚本失败

时间:2016-10-24 09:42:12

标签: bash shell curl continuous-integration sh

我有一个CI脚本,我想通过在后台运行几件事来加快速度。我希望脚本等待所有进程并检查每个进程以查看它是否失败。

这是一个简化:

#!/bin/bash

set -e

bg()
{
    sleep .$[ ( $RANDOM % 10 ) + 1 ]s
}

bg2()
{
    sleep .$[ ( $RANDOM % 10 ) + 1 ]s
    exit 1
}

bg &   # will pass after a random delay 
bg2 &  # will fail after a random delay


# I want the output of the program to be a failure since bg2 fails

2 个答案:

答案 0 :(得分:2)

您可以使用bash中的wait命令等待一个或多个子进程完成以终止,在这种情况下,我们提供PID等待它。此外,wait可以选择不带参数,在这种情况下它等待所有后台进程终止。

实施例: -

#!/bin/bash

sleep 3 &

wait "$!"     # Feeding the non-zero process-id as argument to wait command.
              # Can also be stored in a variable as pid=$(echo $!)

# Waits until the process 'sleep 3' is completed. Here the wait 
# on a single process is done by capturing its process id

echo "I am waking up"

sleep 4 &
sleep 5 &

wait          # Without specifying the id, just 'wait' waits until all jobs 
              # started on the background is complete.

# (or) simply
# wait < <(jobs -p)     # To wait on all background jobs started with (job &)

echo "I woke up again"

更新: -

要在失败时识别作业,最好循环后台作业列表并记录其退出代码以获得可见性。感谢chepner提出的精彩建议。它就像

#!/bin/bash
for p in $(jobs -p)
do
     wait "$p" || { echo "job $p failed" >&2; exit; }
done

答案 1 :(得分:1)

#!/bin/bash

set -e

bg()
{
    sleep .$[ ( $RANDOM % 10 ) + 1 ]s
}

bg2()
{
    sleep .$[ ( $RANDOM % 10 ) + 1 ]s
    exit 1
}

export -f bg
export -f bg2

parallel ::: bg bg2 || echo $? of the jobs failed