`{ { (exit 1); 是什么意思? 1号出口; }; }` 是什么意思?

`{ { (exit 1); 是什么意思? 1号出口; }; }` 是什么意思?

config.status我引用了生成的下一个代码片段configure

if test ! -f "$as_myself"; then
{ { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
{ (exit 1); exit 1; }; }
fi

代码片段中,{ (exit 1); exit 1; };做了什么?只exit在子 shell 中执行的目的是什么?

答案1

执行(exit 1);是触发陷阱的最简单方法ERR。如果set -e有效,它也会触发立即退出。 (触发错误条件需要命令失败;exit子 shell 中的失败值会导致子 shell 失败。)

exit 1;不会做这两件事。

So{(exit 1); exit 1;}可用于首先生成ERR陷阱,这可能会执行一些对调试有用的操作,然后终止脚本并显示错误指示。

autoconf但文件中的情况并非如此。autoconf脚本依靠EXIT陷阱来清理运行期间创建的临时文件。大多数 shell(包括)将在调用陷阱之前bash根据命令中提供的值设置状态。这可以允许陷阱检测它是从错误还是正常终止中调用,并且还允许它确保在陷阱操作结束时正确设置退出状态。exitEXITEXIT

然而,显然有些外壳不合作。这是来自autoconf手动的:

某些 shell 脚本(例如由 生成的脚本autoconf)在退出前使用陷阱进行清理。如果最后一个 shell 命令以非零状态退出,则陷阱也会以非零状态退出,以便调用者可以知道发生了错误。

不幸的是,在某些 shell(例如 Solaris)中/bin/sh,退出陷阱会忽略 exit 命令的参数。在这些 shell 中,陷阱无法确定它是由普通退出调用还是由退出 1 调用。不要直接调用 exit,而是使用AC_MSG_ERROR可解决此问题的宏。

解决方法是确保$?具有退出状态exit命令被执行,因此当EXIT陷阱执行时它肯定会具有该值。事实上,正是这个AC_MSG_ERROR宏插入了奇怪的代码,并带有多余的大括号。

答案2

据我所知,这样做没有任何目的,没有什么可以通过启动子shell然后立即退出来直接实现。

像这样的事情很可能是自动生成代码的副作用 - 在某些情况下,可能会在子 shell 中执行其他命令,而这些命令是有意义的exit 1。最终,通过允许生成代码插入一些在某些情况下没有任何功能的语句,生成代码很有可能在某种程度上得到简化,而每次生成“干净的代码”会更加复杂。要么是那个,要么是生成上述代码的代码写得不好:)

自由使用{...}是另一个例子,它们中的大多数都是多余的,但是编写在每种情况下插入它们的代码更容易(也许在某些情况下您想要重定向块的输出/输入)而不是区分那些不需要的地方并省略它们。

答案3

(exit 1)是一种简单的、可能是最简单的获取特定退出代码的方法(当然,在 1 的特殊情况下,还有更简单的方法)。但这不是本例的原因,因为没有检查退出代码。

放入子 shell 的目的exit可能是不退出脚本(尽管使用 exit 来生成特定的退出代码)。

相关内容