dh_usrlocal 实际上做了什么

dh_usrlocal 实际上做了什么

dh_usrlocal 联机帮助页对我来说听起来有点神秘:

它在包构建目录中查找 usr/local 的子目录,并删除它们,用维护者脚本片段替换它们(除非使用 -n )以在安装时创建目录,并在删除包时以某种方式删除它们符合 Debian 政策。这些片段由 dh_installdeb 插入到维护者脚本中。有关 debhelper 维护者脚本片段的说明,请参阅 dh_installdeb(1)。

维护者脚本、片段、-n……好吧,但是什么是目的?它真的只是创建(空?)目录吗?

有好心人可以用更实际的方式向我解释一下吗?我应该阅读政策的哪一部分?我应该关心我的应用程序是否安装了PREFIX=/usr

答案1

目的是帮助该软件包遵守政策。根据 Debian 政策(以及 IIRC、文件系统层次结构标准或FHS),官方 Debian 软件包是不允许拥有以下文件或目录/usr/local- 该目录树属于本地系统管理员。

https://www.debian.org/doc/debian-policy/ch-opersys.html#s9.1.2

(粗体强调是我加的)

9.1.2.特定地点的计划

根据 FHS 的规定,套餐不得将任何文件放置在 /usr/local 中,或者将它们放入文件系统存档中以由 dpkg 解压,或者在维护者脚本中操作它们。

然而,该软件包可能会在 /usr/local 下创建空目录以便系统管理员知道在哪里放置特定于站点的文件。这些不是 /usr/local 中的目录,而是 /usr/local 中目录的子目录。如果这些目录 (/usr/local/*/dir/) 为空,则应在删除软件包时将其删除。

请注意,这仅适用于 /usr/local 下的目录,不适用于 /usr/local 中的目录。软件包不得在目录 /usr/local 本身中创建子目录,FHS 第 4.5 节中列出的子目录除外。但是,您可以根据需要在它们下面创建目录。您不得删除 4.5 中列出的任何目录,即使它们是您创建的。

由于 /usr/local 可以从远程服务器以只读方式挂载,因此这些目录必须由 postinst 和 prerm 维护者脚本创建和删除,并且不能包含在 .deb 存档中。如果这些操作中的任何一个失败,这些脚本一定不会失败。

例如,emacsen-common 包可能包含类似的内容

if [ ! -e /usr/local/share/emacs ]; then
    if mkdir /usr/local/share/emacs 2>/dev/null; then
        if chown root:staff /usr/local/share/emacs; then
            chmod 2775 /usr/local/share/emacs || true
        fi
    fi
fi

在其 postinst 脚本中,以及

rmdir /usr/local/share/emacs/site-lisp 2>/dev/null || true
rmdir /usr/local/share/emacs 2>/dev/null || true

在 prerm 脚本中。 (注意,这种形式是为了确保如果脚本被中断,目录 /usr/local/share/emacs 仍然会被删除。)

如果您确实在 /usr/local 中创建目录以用于本地添加软件包,则应确保 /usr/local 中的设置优先于 /usr 中的等效设置。

但是,由于 /usr/local 及其内容仅供本地管理员专用,因此包不能依赖于 /usr/local 中是否存在文件或目录来进行正常操作。

/usr/local 目录本身以及该包创建的所有子目录应(默认情况下)具有权限 2775(组可写和设置组 ID)并由 root:staff 所有。

也可以看看https://wiki.debian.org/FilesystemHierarchyStandard

dh_usrlocal从包中删除任何此类目录,并将其替换为包脚本(.postinst.prerm脚本)中的代码,以便按照策略中给出的示例在安装/卸载时创建/删除它们。

这似乎没有什么实际区别,因为目录仍然在安装时创建并在卸载时删除,但 Debian 认为软件包未能遵守策略与任何其他错误一样严重 - 一致且严格地遵守策略是Debian 软件包质量保证的一个主要因素。

相关内容