对于 Debian 安装程序脚本,如果 postinst 脚本中有错误或用户使用 Ctrl+C 终止进程,是否可以回滚整个安装?看起来即使我返回一个非零退出代码,它仍然会安装程序。
1 回答
不。
嗯,这可能是可能的,因为postinst
以 root 身份运行并且可以做各种棘手的事情来颠覆系统。但是dpkg
尽量使用锁来防止这种情况发生,因为维护者脚本不应该改变包的“期望”状态。
这个我还没有验证过,但是我猜如果你postinst
用Ctrl+C取消一个脚本,它算作postinst
失败,并且包被标记为处于half-configured
状态。因此,它并没有完全安装,但是,是的,用户可能很难区分。
因此,为您提供一些潜在的解决方案:
如果您的包提供服务,您可以有一个标志(例如,某个地方的文件,如
/var/lib/$yourpackage
),仅在包完全安装时(在 末尾postinst
)设置。该服务将在启动时检查此标志,如果它不存在,则该服务将不会启动,甚至可能会打印一条关于未完全安装的警告消息。此解决方案在某些方面类似于完全卸载软件包。请记住取消设置标志或删除文件prerm
开头和开头的文件postinst
(以防在升级期间而不是在第一次安装时出现 Ctrl+C)。您可以在 中捕获 Ctrl+C (
SIGINT
)postinst
,并打印一条类似“”的消息This package will be left in the Failed-Config state. To remove it entirely, run (dpkg -P/apt purge/whatever). To attempt to complete installation, run dpkg --configure -a.
(然后postinst
使用非零退出代码退出 ,以便 dpkg 知道失败。)如果您能够做到这一点,请让您的用户更加了解他们何时安装了损坏的软件包,以便他们可以快速做出重新安装或删除的决定。
你可以把你
postinst
最有可能是 Ctrl+C'd 的任何东西移到preinst
. 如果preinst
失败,那么dpkg
将调用postrm
withabort-install
动作。预计postrm
将清理preinst
已经做过的任何事情。如果postrm
成功,则该软件包被干净地完全卸载。当然,如果这一步postinst
需要解压缩包中的文件并呈现,这不是一个真正的选择。