【问题标题】:bash on ubuntu 16: set -e not inheriting inside subshellubuntu 16 上的 bash:set -e 不在 subshell 内部继承
【发布时间】:2017-08-02 17:12:06
【问题描述】:
当我运行这个命令时
set -e; echo $(echo "$-");
我得到himBH 作为输出。我期待字母 e 包含在输出中。怎么回事?
我在 Ubuntu 16.04.1 LTS 上使用
GNU bash,版本 4.3.46(1)-release (x86_64-pc-linux-gnu)
【问题讨论】:
-
set -e 是... 有争议的 -- 它的行为因 shell 版本而异,而且通常非常令人惊讶。考虑阅读BashFAQ #105。
标签:
bash
debugging
ubuntu
exit-code
fail-fast
【解决方案1】:
命令替换不会继承 errexit 选项,除非您处于 POSIX 模式或使用 inherit_errexit shell 选项(添加到 bash 4.4)。
192% bash -ec 'echo "$(echo "$-")"'
hBc
192% bash --posix -ec 'echo "$(echo "$-")"'
ehBc
192% bash -O inherit_errexit -ec 'echo "$(echo "$-")"' # 4.4+
ehBc
【解决方案2】:
这个问题!
在这方面工作了几个小时,直到我找到了 htis。
我无法将set -e 继承到子shell。
这是我的概念证明:
#!/usr/bin/env bash
set -euo pipefail
# uncomment to handle failures properly
# shopt -s inherit_errexit
function callfail() {
echo "SHELLOPTS - callfail - $SHELLOPTS" >&2
local value
value=$(fail)
echo "echo will reset the result to 0"
}
function fail() {
echo "SHELLOPTS - fail - $SHELLOPTS" >&2
echo "failing" >&2
return 1
}
function root() {
local hello
hello=$(callfail)
echo "nothing went bad in callfail"
callfail
echo "nothing went bad in callfail"
}
root
没有shopt -s inherit_errexit的执行:
$ ./test.sh
SHELLOPTS - callfail - braceexpand:hashall:interactive-comments:nounset:pipefail
SHELLOPTS - fail - braceexpand:hashall:interactive-comments:nounset:pipefail
failing
nothing went bad in callfail
SHELLOPTS - callfail - braceexpand:errexit:hashall:interactive-comments:nounset:pipefail
SHELLOPTS - fail - braceexpand:hashall:interactive-comments:nounset:pipefail
failing
使用shopt -s inherit_errexit 执行:
$ ./test.sh
SHELLOPTS - callfail - braceexpand:errexit:hashall:interactive-comments:nounset:pipefail
SHELLOPTS - fail - braceexpand:errexit:hashall:interactive-comments:nounset:pipefail
failing