第一次出错时make bash wait命令失败

时间:2015-09-16 08:37:20

标签: bash

我有一个bash脚本,它可以并行化一些耗时的命令,到目前为止它运行得很好。我使用wait命令如下:

docker pull */* &
docker pull */* &
docker pull */* &
docker pull */* &
docker pull */* &
docker pull */* &
docker pull */* &
composer install -n &
wait

现在我希望这个脚本中止所有命令并在其中一个命令失败时给出退出代码。怎么做到这一点?

注意:* / *是泊坞窗图像名称,对于上下文不重要

2 个答案:

答案 0 :(得分:2)

这需要wait -n的bash。

这里的技巧是保留您生成的子进程列表,然后单独等待它们(按照它们完成的顺序)。然后,您可以检查已完成的流程的返回代码,如果失败则将其中的大部分内容删除。例如:

#!/bin/bash

# Remember the pid after each command, keep a list of them.
# pidlist=foo could also go on a line of its own, but I
# find this more readable because I like tabular layouts.
sleep 10 & pidlist="$!"
sleep 10 & pidlist="$pidlist $!"
sleep 10 & pidlist="$pidlist $!"
sleep 10 & pidlist="$pidlist $!"
sleep 10 & pidlist="$pidlist $!"
sleep 10 & pidlist="$pidlist $!"
false    & pidlist="$pidlist $!"

echo $pidlist

# $pidlist intentionally unquoted so every pid in it expands to a
# parameter of its own. Note that $i doesn't have to be the PID of
# the process that finished, it's just important that the loop runs
# as many times as there are PIDs.
for i in $pidlist; do
    # Wait for a single process in the pid list to finish,
    # check if it failed,
    if ! wait -n $pidlist; then
        # If it did, kill the lot. pipe kill's stderr
        # to /dev/null so it doesn't complain about
        # already-finished processes not existing
        # anymore.
        kill $pidlist 2>/dev/null

        # then exit with a non-zero status.
        exit 1
    fi
done

答案 1 :(得分:0)

如果命令的返回值为0,则表示成功,其他表示错误。因此,您可以创建一个函数,并在每个命令之前调用它。 (这只适用于删除&)

valid() {
    if "$@"; then 
        return
    else
        exit 1
    fi
}

valid docker pull */* 
valid docker pull */* 
valid docker pull */* 
valid docker pull */* 
valid docker pull */* 
valid docker pull */*
valid docker pull */* 
valid composer install -n 
wait

另一种选择是放

set -e

在脚本的开头。

  

如果是一个简单的命令,这将导致shell立即退出   以非零退出值退出。

额外注意事项:

如果您有自己的Docker Registry,则不需要并行提取图像。 Docker Registry 2.0 ,与 Docker 1.7.0 及以上版本配合使用,可以并行下载图像层,这使得程序更加快速,因此您不需要; t必须同时拉出所有图像。

Source