如果任何功能并行失败,请停止 bash

问题描述 投票:0回答:2

我有一个 BASH,可以在我的 BASH 中并行运行 3 个函数。

        functionA () {
            ......
            my command || { echo "ERROR!!" >> $LOG_FILE ; exit 1 ;}
        }

        functionB () {
            ......
            my command || { echo "ERROR!!" >> $LOG_FILE ; exit 1 ;}
        }
       
        functionC () {
            ......
            my command || { echo "ERROR!!" >> $LOG_FILE ; exit 1 ;}
        }

functionA &
functionB &
functionC &
wait

我在所有函数中都有一些这样的错误处理命令:

my command || { echo "ERROR!!" >> $LOG_FILE ; exit 1 ;}

我注意到即使我在所有功能中都有用于错误处理的出口 1,但其他功能仍在继续。如果任何函数失败,如何停止 bash 并返回退出代码 1?

我是 BASH 的新手,感谢任何帮助!

bash ubuntu parallel-processing
2个回答
4
投票

更新: 使用大量子进程同时终止测试我的原始代码表明需要某种独占锁定机制;我使用广泛可用的

mktemp -d
和符号链接实现了一个简单的(即原子的)。

#!/bin/bash

lockdir=$(mktemp -d) || exit "$?"

trap 'exit 1' ABRT
trap 'mv "$lockdir" "$lockdir~" && rm -rf "$lockdir~"; kill 0' EXIT

diex() { ln -s _ "$lockdir/.lock" 2> /dev/null && kill -ABRT "$$"; }

{ sleep 1; echo "ERROR!!"; diex; } &
{ sleep 2; echo "HELLO!!"; } &

wait

注:这里我假设

"$lockdir~"
不存在。如果它对你来说不够好,那么你可以使用
mktemp -d
创建另一个目录,并在删除它之前将其用作垃圾箱。

说明:

想法是让子进程在失败时用

kill -ABRT "$$"
通知主脚本。
我选择了
SIGABRT
信号,因为它适合中止的目的,但它具有禁用通常在接收
SIGABRT
时自动生成核心转储的效果。如果您运行的操作系统支持
SIGUSR1
SIGUSR2
那么您可以使用它。

  1. 在脚本的开头,您使用
    trap
    定义了一些信号侦听器,并关联了一个在捕获指定类型的信号时要运行的命令:
  • EXIT
    信号的侦听器(例如由主脚本上下文中的
    exit
    命令触发)将使用
    kill 0
    终止脚本及其所有子进程。

  • SIGABRT
    的监听器(由子进程发送)不仅会产生一个
    EXIT
    信号还会设置退出状态为
    1

  1. 锁定机制是为了防止发送一个以上的
    SIGABRT
    信号。

1
投票

GNU 并行

--halt-on-error now,1

GNU parallel 是这类应用程序的赢家。安装:

sudo apt install parallel

测试一下:

myfunc() {
    echo "start: $1"
    sleep "$1"
    [ $1 -eq 3 ] && exit 1
    echo "end: $1"
}
export -f myfunc
parallel --lb --halt-on-error now,fail=1 myfunc ::: 1 2 3 4
echo "exit status: $?"

结果:

start: 3
start: 1
start: 2
start: 4
end: 1
end: 2
parallel: This job failed:
myfunc 3
exit status: 1

所以我们看到

4
从未完成,因为
3
在它之前失败了。

的:

start: 3
start: 1
start: 2
start: 4

立即出现,

end: 1
一秒后,
end: 2
再过一秒,再过一秒最后:

parallel: This job failed:
myfunc 3

在 Ubuntu 22.04 上测试。

备注:

© www.soinside.com 2019 - 2024. All rights reserved.