Ern*_*A C 39 shell shell-script exit subshell
考虑这个片段:
stop () {
echo "${1}" 1>&2
exit 1
}
func () {
if false; then
echo "foo"
else
stop "something went wrong"
fi
}
Run Code Online (Sandbox Code Playgroud)
通常当func被调用时它会导致脚本终止,这是预期的行为。但是,如果它在子shell中执行,例如在
result=`func`
Run Code Online (Sandbox Code Playgroud)
它不会退出脚本。这意味着调用代码每次都必须检查函数的退出状态。有没有办法避免这种情况?这set -e是为了什么?
Sté*_*las 40
例如,您可以决定退出状态 77 表示退出任何级别的子shell,然后执行
set -E
trap '[ "$?" -ne 77 ] || exit 77' ERR
(
echo here
(
echo there
(
exit 12 # not 77, exit only this subshell
)
echo ici
exit 77 # exit all subshells
)
echo not here
)
echo not here either
Run Code Online (Sandbox Code Playgroud)
set -E与ERRtraps结合使用有点像 的改进版本,set -e因为它允许您定义自己的错误处理。
在zsh中,ERR陷阱是自动继承的,所以你不需要set -E,你也可以将陷阱定义为TRAPERR()函数,通过修改它们$functions[TRAPERR],比如functions[TRAPERR]="echo was here; $functions[TRAPERR]"
der*_*ert 13
您可以kill $$在调用 之前终止原始外壳 ( ) exit,这可能会奏效。但:
相反,您可以使用Bash FAQ中的几种方法之一来传回值。不幸的是,它们中的大多数都不是很好。您可能只是在每次函数调用后都无法检查错误(-e有很多问题)。要么,要么切换到 Perl。
Sté*_*nez 10
作为 的替代方案kill $$,您也可以尝试kill 0,它可以在嵌套子shell 的情况下工作(所有调用方和侧进程都将收到信号)……但它仍然是残酷和丑陋的。