执行(exit 1);
是触发ERR
陷阱的最简单方法。如果有效,它还将触发立即退出set -e
。(触发错误条件需要命令失败;exit
子shell中的失败值会导致子shell失败。)
exit 1;
不会做任何事情。
因此{(exit 1); exit 1;}
可以用来首先生成ERR
陷阱,该陷阱可能会为调试目的做一些有用的事情,然后使用错误指示终止脚本。
但这不是autoconf
文件中正在发生的事情。autoconf
脚本依靠EXIT
陷阱来清除运行期间创建的临时文件。大多数shell(包括shell)bash
将exit
在调用EXIT
陷阱之前根据命令中提供的值来设置状态。这可以使EXIT
陷阱能够检测到它是从错误中调用还是从正常终止中被调用,还可以确保陷阱操作结束时正确设置了退出状态。
但是,显然有些外壳无法配合使用。这是autoconf
手册的引文:
有些shell脚本(例如由生成的shell脚本)autoconf
在退出之前使用陷阱进行清理。如果最后一个shell命令以非零状态退出,则陷阱也以非零状态退出,以便调用程序可以知道发生了错误。
不幸的是,在某些Shell中,例如Solaris /bin/sh
,出口陷阱会忽略出口命令的参数。在这些shell中,陷阱无法确定是由普通出口还是由出口1调用的。与其直接调用exit,不如使用AC_MSG_ERROR
具有解决此问题的方法的宏。
解决方法是确保$?
有退出状态之前的exit
执行命令,这样当它必定会对这个值EXIT
执行陷阱。实际上,正是AC_MSG_ERROR
宏插入了好奇的代码,并带有多余的花括号。
false
而不是执行(exit 1)
?