我为我的
shell脚本启用了errexit(和pipefail),因为这是我通常想要的行为.但是,偶尔我想捕获错误并以特定方式处理它们.
我知道对包含布尔运算符的命令禁用errexit或者将其用作条件(如果,等等)
例如
git push && true echo "Pushed: $?"
将在成功时回应“推动:0”,或者在失败时回应“推动:别的”.
但是,如果我想让子shell启用errexit,那么我希望捕获此子shell的退出代码?
例如:
#!/usr/bin/env bash set -o errexit ( git push echo "Hai" ) && true echo "Did it work: $?"
问题是,bash看到&& boolean运算符并禁用子shell的errexit.这意味着“海”总是回声.那是不可取的.
如何在这个子shell中启用errexit,并捕获子shell的状态代码,而不让出口代码终止外壳而不必在整个地方不断启用和禁用errexit?
更新
看来我偶然发现许多贝壳爱好者争论不休:
http://austingroupbugs.net/view.php?id=537#bugnotes
基本上,标准说了些什么,解释器忽略了它,因为标准似乎不合逻辑,但现在像Bash这样的解释器确实令人困惑的语义,没有人想要解决它.
不幸的是,陷阱< blah> EXIT不能用于做我想要的事情,因为陷阱基本上只是信号的中断处理程序,没有办法在预定的点继续执行脚本(就像你在try..finally块中使用一样)其他语言).
一切都很糟糕
基本上,据我所知,绝对没有理智的方法来执行错误处理.你的选择是:
#!/usr/bin/env bash set -e # Some other code set +e ( git push || exit $? echo "Hai" ) echo "Did it work: $?" set -e
要么:
#!/usr/bin/env bash set -e ( git push && echo "Hai" || exit $? ) && true echo "Did it work: $?"
有点让你想知道为什么你首先打扰set -e!