为什么用errexit不能与命令列表一起使用?

Aug*_*rom 8 error-handling sh

如果我以普通用户身份运行以下shell脚本,它将按预期在第三行中止:

set -o errexit

echo foo > /bar
echo $?
Run Code Online (Sandbox Code Playgroud)

这是输出:

$ sh test1.sh 
test.sh: 3: test.sh: cannot create /bar: Permission denied
Run Code Online (Sandbox Code Playgroud)

但是,如果echo命令是复合列表的一部分,则执行失败的命令后将继续执行并显示退出代码:

set -o errexit

{ echo foo; } > /bar
echo $?
Run Code Online (Sandbox Code Playgroud)

这是输出:

$ sh test2.sh 
test.sh: 3: test.sh: cannot create /bar: Permission denied
2
Run Code Online (Sandbox Code Playgroud)

脚本为什么不会终止?另一方面,如果将花括号更改为括号,则其工作方式将与我期望的一样。

che*_*ner 4

POSIX 规范规定,如果复合命令发生重定向错误,shell“可能会退出”

bash如果复合命令是子 shell 命令 ( ),则选择退出,(...)否则选择不退出。我不知道这种区别的理由;这可能是历史性的。

set -e有很多怪癖,而且常常不会按照你期望的方式行事。许多人建议您不要使用它。