虽然Bash 手册页指出:
如果失败的命令是 ... 在 && 或 || 中执行的命令的一部分,则不会执行 ERR 陷阱 列表 ...
我希望 subshell 中的代码处于不同的上下文中,并且不受上述限制。下面的代码表明,即使是 subshell 也不能免受此限制:
#!/bin/bash
main()
{
local Arg="$1"
(
set -e
echo "In main: $Arg"
trap MyTrap ERR
$(exit 1)
echo "Should not get here"
)
return 1
}
MyTrap()
{
echo "In MyTrap"
}
main 1
[[ $? -eq 0 ]] || echo "failed"
echo
main 2 || echo "failed"
上面的代码有以下输出:
In main: 1
In MyTrap
failed
In main: 2
Should not get here
failed
我目前的解决方法是使用文件持久性来保存错误状态,MyTrap
然后在调用者中检查返回码。例如:
MyTrap()
{
echo "_ERROR_=$?" > $HOME/.persist
echo "In MyTrap"
}
main 1
[[ -f $HOME/.persist ]] && . $HOME/.persist || _ERROR_=0
[[ $_ERROR_ -eq 0 ]] || echo "failed"
上面的输出现在是:
In main: 1
In MyTrap
failed
所以,问题是:是否可以找到一种方法来执行 set -e/ERR 子shell 捕获,它不受上述解决方法的影响&&
和限制?||
注:此问题适用于:
- Bash 4.2 及更高版本
- Red Hat 7、CentOS 7 和相关发行版(即不是 Debian 等)
- 不得使用第三方软件。软件包必须可用,例如,通过 [CentOS-7-x86_64-DVD-1611.iso][2] 存储库 iso 中的 OS-provider 软件包(对于 RHEL 7、Fedora 7 等类似)。