Bash set -e 不立即退出并出现 pipefail
Bash set -e not exiting immediately with pipefail
set -eo pipefail
commandThatFails || exitFunction
exitFunction
所以这个脚本是 运行 exitMethod 两次...我认为 set -e
在任何非零退出代码上立即退出并且 set -o pipefail
确保在管道期间任何失败都是最终退出状态代码不是最近的命令?
所以我想:
- commandThatFails
- 执行 exitFunction
- set -o pipefail returns 非零退出代码作为第一个命令失败
- set -e 检测到非零退出代码并立即退出
在文档中指出:
The shell does not exit if the command that fails is part of the
command list immediately following a while or until keyword, part of
the test in an if statement, part of any command executed in a && or
|| list except the command following the final && or ||, any command
in a pipeline but the last, or if the command’s return status is being
inverted with !. If a compound command other than a subshell returns a
non-zero status because a command failed while -e was being ignored,
the shell does not exit. A trap on ERR, if set, is executed before the
shell exits.
我以为exitfunction是command following the final ||
所以会被计算并立即退出。
我可以通过以下方式解决问题:
commandThatFails || { exitFunction; exit 1; }
但这似乎不是处理此问题的更优雅的方式,任何想法都值得赞赏!
||
是流量控制算子,不是管道组件。 pipefail
对它没有影响。
如果 set -e
导致流量控制操作符退出,那么您的脚本 运行 的 else
分支永远不会处于活动状态;这将完全没有用。
因此,&&
和 ||
抑制其左侧的 set -e
行为,就像 if condition; then success; else fail; fi
抑制 condition
的行为一样.
一般做法是让你的exitFunction
实际调用exit
,所以你可以这样写:
die() {
rc=$?
(( $# )) && printf '%s\n' "$*" >&2
exit "$(( rc == 0 ? 1 : rc ))"
}
commandThatFails || die "commandThatFails failed"
...但是如果你想先调用其他东西,是的,你需要使用分组,就像你在问题中所做的那样。
set -eo pipefail
commandThatFails || exitFunction
exitFunction
所以这个脚本是 运行 exitMethod 两次...我认为 set -e
在任何非零退出代码上立即退出并且 set -o pipefail
确保在管道期间任何失败都是最终退出状态代码不是最近的命令?
所以我想:
- commandThatFails
- 执行 exitFunction
- set -o pipefail returns 非零退出代码作为第一个命令失败
- set -e 检测到非零退出代码并立即退出
在文档中指出:
The shell does not exit if the command that fails is part of the command list immediately following a while or until keyword, part of the test in an if statement, part of any command executed in a && or || list except the command following the final && or ||, any command in a pipeline but the last, or if the command’s return status is being inverted with !. If a compound command other than a subshell returns a non-zero status because a command failed while -e was being ignored, the shell does not exit. A trap on ERR, if set, is executed before the shell exits.
我以为exitfunction是command following the final ||
所以会被计算并立即退出。
我可以通过以下方式解决问题:
commandThatFails || { exitFunction; exit 1; }
但这似乎不是处理此问题的更优雅的方式,任何想法都值得赞赏!
||
是流量控制算子,不是管道组件。 pipefail
对它没有影响。
如果 set -e
导致流量控制操作符退出,那么您的脚本 运行 的 else
分支永远不会处于活动状态;这将完全没有用。
因此,&&
和 ||
抑制其左侧的 set -e
行为,就像 if condition; then success; else fail; fi
抑制 condition
的行为一样.
一般做法是让你的exitFunction
实际调用exit
,所以你可以这样写:
die() {
rc=$?
(( $# )) && printf '%s\n' "$*" >&2
exit "$(( rc == 0 ? 1 : rc ))"
}
commandThatFails || die "commandThatFails failed"
...但是如果你想先调用其他东西,是的,你需要使用分组,就像你在问题中所做的那样。