子shell失败时为什么不用bash标志-e exit?

Ste*_*ala 15 bash

我在这里有点困惑.我的目标是当脚本中的任何命令失败时,使用非零退出代码退出bash脚本.使用-e标志,我认为即使使用子shell也是如此.以下是一个简化示例:

#!/bin/bash -e

(false)

echo $?
echo "Line reached!"
Run Code Online (Sandbox Code Playgroud)

这是运行时的输出:

[$]>Tests/Exec/continuous-integration.sh 
1
Line reached!
Run Code Online (Sandbox Code Playgroud)

Bash版本:CentOS上的3.2.25

Sha*_*iri 14

-e选项适用于我们使用的当前 shell、子 shell、函数等-E

形成人bash

-E如果设置,则 ERR 上的任何陷阱都会由 shell 函数、命令替换和在子 shell 环境中执行的命令继承。

对于高级用户,我们有一种严格的模式:

# one line
set -Eeuo pipefail
Run Code Online (Sandbox Code Playgroud)
  • -E上面解释过
  • -e立即退出
  • -u找到未绑定变量退出
  • -o设置选项
  • pipefail如果管道出现故障则退出

如果你想使用严格模式作为函数

################################################################################
#
# bash strict mode
#
################################################################################
strict_mode(){
    set -T # inherit DEBUG and RETURN trap for functions
    set -C # prevent file overwrite by > &> <>
    set -E # inherit -e
    set -e # exit immediately on errors
    set -u # exit on not assigned variables
    set -o pipefail # exit on pipe failure
}
strict_mode;
Run Code Online (Sandbox Code Playgroud)


Aus*_*ips 11

看起来好像这与你的版本有关bash.在我有权访问的机器上,bash版本3.1.17和3.2.39表现出这种行为,bash 4.1.5没有.

虽然有点难看,但在两个版本中都可以使用的解决方案可能是这样的:

#!/bin/bash -e

(false) || exit $?

echo $?
echo "Line reached!"
Run Code Online (Sandbox Code Playgroud)

bash源changelog中有一些注释与set -e选项的bug有关.