错误处理

错误处理的重要性

良好的错误处理很重要,因为

  • 必须在 Portage 尝试将损坏或不完整的软件包安装到活动文件系统之前检测到错误。如果构建失败没有被捕获,一个工作的软件包可能会被取消合并并替换为空。
  • 在收到错误报告时,如果您确切地知道哪个调用导致了错误,而不是仅仅知道,例如,src_compile 中的某个地方出错了,那么找出问题所在就容易得多。
  • 良好的错误处理和通知可以帮助减少为软件包收到的错误报告数量。

die 函数

die 函数应用于指示致命错误并中止构建。它的参数应该是要显示的消息。

虽然 die 在没有参数的情况下也能正常工作,但始终应该提供简短的消息,以方便错误识别。当一个函数可以在多个地方退出时,这一点尤其重要。

Ebuild 助手在失败时会自动退出。一些 eclass 提供的函数会在失败时自动退出,而另一些则不会。如有疑问,开发人员应检查 eclass 参考

有时,提前显示额外的错误信息可能会有用。使用 eerror 来执行此操作。请参阅 消息

die 和子 shell

以下代码将无法按预期工作,因为 die 在子 shell 中。

[[ -f foorc ]] && ( update_foorc || die "Couldn't update foorc!" )

重写此代码的正确方法是使用 if 块

if [[ -f foorc ]] ; then
	update_foorc || die "Couldn't update foorc!"
fi

在使用管道时,会引入子 shell,因此以下操作不安全

cat list | while read file ; do eapply ${file} ; done

使用输入重定向(参见 滥用 cat)可以避免此问题

while read file ; do eapply ${file} ; done < list

assert 函数和 PIPESTATUS

在使用管道时,简单的条件语句和对 $? 的测试无法正确检测到除链中最后一个命令以外的任何命令发生的错误。为了解决这个问题,bash 提供了 PIPESTATUS 变量,Portage 提供了 assert 函数来检查此变量。

bzip2 -dc "${DISTDIR}/${VIM_RUNTIME_SNAP}" | tar -xf -
assert

如果您需要了解 PIPESTATUS 的详细信息,请参阅 bash 手册页。大多数情况下,assert 足够了。

nonfatal 命令

如果预期从 ebuild 助手函数获得非零退出状态,您可以在 nonfatal 函数下调用它。然后,该命令不会在失败时退出,而是会返回非零退出状态,如以下示例所示

src_test() {
	if ! nonfatal emake check ; then
		local a
		eerror "Tests failed. Looking for files to add to your bug report..."
		while IFS='' read -r -d $'\0' a ; do
			eerror "    ${a}"
		done < <(find "${S}" -type f -name '*.log' -print0)
		die "Make check failed"
	fi
}