我按以下方式构建了我的 Debian 软件包
preinst script
它向用户显示 EULA 并要求选择“y”或“n”。postinst script
它安装软件包并更新 initrd 映像。prerm script
,在卸载软件包之前检查条件,如果条件匹配,则从 prerm 退出exit 1
。postrm script
如果签入 prerm 脚本失败并更新 initrd 映像,则卸载程序包。
现在我有以下问题
假设软件包已经安装在计算机上,并且用户正在尝试重新安装或升级它。现在,如果用户对 EULA 说“是”,那么 debian 会做什么?我观察到它只是卸载以前安装的软件包并重新安装它,这完全没问题。但是如果用户对 EULA 说“n”,我将如何退出卸载过程?我在 preinst 脚本中添加了它
exit 1
,但它不起作用。我观察到,如果你说dpkg -i package
,debian 首先检查包是否已经安装,如果包已经安装,那么它甚至在调用 preinst 脚本之前解压包(`使用 lsmod 检查它)因此,如果您对 EULA 说“n”,它就会开始回滚更改,即通过调用 postinst 脚本重新安装解压的软件包,这对最终用户来说看起来很奇怪,因为用户已经对 EULA 说“n”。我尝试添加一个检查模块是否为现在不要重新安装它,但正如我所说,每当您说 dpkg -i package 时,debian 首先会删除该模块并导致我的检查失败。那么,如果用户拒绝 EULA,如何避免重新安装软件包呢?如果我说
dpkg -r package
和我的prerm script fails and exits with status 1
。这里会发生与上面相同的事情。如果你说dpkg -r package
,debian 在调用 prerm 脚本之前卸载包,然后它会检查条件是否prerm
匹配,然后从中退出并通过调用 postinst 脚本开始回滚更改这又是一种奇怪的行为。
我知道这是 Debian 的默认行为,但是如果我想覆盖默认行为怎么办?
答案1
这种事情不应该在(pre|post)|(inst|rm)
脚本中完成。(pre|post)|(inst|rm)
脚本应该是幂等的和非交互的。
相反,您想要做的是提供一个 debconf 模板,该模板需要回答问题才能完全安装软件包。
如果您想要示例,请查看sun-java*
包。您可以在此处查看 debconf 模板:dlj.模板。
这些sun-java*
软件包特别提供了在安装 Java 之前必须获得批准的许可证。
这是一个不同的模板中的示例问题(因为许可证太长,无法在此处重现):
Template: shared/accepted-sun-dlj-v1-1
Type: boolean
Default: false
_Description: Do you accept the DLJ license terms?
In order to install this package, you must accept the license terms, the
"Operating System Distributor License for Java" (DLJ), v1.1. Not accepting
will cancel the installation.
Template
是 debconf 数据库中对象的名称。它必须是唯一的。Type
是值的类型。在本例中,它是一个布尔值,意味着 debconf 将询问是/否问题。Default
给出呈现给用户时最初选择的响应(或者如果优先级不够高而无法看到问题,则自动选择的响应)。_Description
是个标题对话框的。- 剩下的就是对话框中显示的文本。它必须缩进一个空格。
- 模板由以下分隔符分隔空行(IE,
\n\n
)
有关更多信息,请参阅 Debian 的debconf 规范文档和开发人员参考第 6.5 节。