如果任何函数并行失败,则停止 bash
Stop bash if any of the functions fail in parallel
我的 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 和 return 退出代码 1?
我是 BASH 的新手,非常感谢您的帮助!
update: 用大量 sub-processes 同时终止测试我的原始代码表明需要某种独占锁定机制;我使用广泛可用的 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
创建另一个目录,并在删除它之前将其用作 trash-bin。
解释:
想法是让 sub-processes 在失败时用 kill -ABRT "$$"
通知主脚本。
我选择 SIGABRT
信号是因为它适用于中止的目的,但它具有禁用通常在接收 SIGABRT
时自动生成 core-dump 的效果。如果您 运行 正在使用支持 SIGUSR1
和 SIGUSR2
的 OS,那么您可以改用它。
- 在脚本的开头,您定义了一些带有
trap
的信号侦听器,并在捕获指定类型的信号时将命令关联为 运行:
EXIT
信号的侦听器(例如由主脚本上下文中的 exit
命令触发)将终止脚本及其所有 sub-processes kill 0
.
SIGABRT
的侦听器(由sub-processes发送)不仅会生成EXIT
信号,还会将退出状态设置为1
.
- 锁定机制是为了防止发送一个以上的
SIGABRT
信号。
我的 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 和 return 退出代码 1?
我是 BASH 的新手,非常感谢您的帮助!
update: 用大量 sub-processes 同时终止测试我的原始代码表明需要某种独占锁定机制;我使用广泛可用的 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
创建另一个目录,并在删除它之前将其用作 trash-bin。
解释:
想法是让 sub-processes 在失败时用 kill -ABRT "$$"
通知主脚本。
我选择 SIGABRT
信号是因为它适用于中止的目的,但它具有禁用通常在接收 SIGABRT
时自动生成 core-dump 的效果。如果您 运行 正在使用支持 SIGUSR1
和 SIGUSR2
的 OS,那么您可以改用它。
- 在脚本的开头,您定义了一些带有
trap
的信号侦听器,并在捕获指定类型的信号时将命令关联为 运行:
EXIT
信号的侦听器(例如由主脚本上下文中的exit
命令触发)将终止脚本及其所有 sub-processeskill 0
.SIGABRT
的侦听器(由sub-processes发送)不仅会生成EXIT
信号,还会将退出状态设置为1
.
- 锁定机制是为了防止发送一个以上的
SIGABRT
信号。