![dh_usrlocal 实际上做了什么](https://linux22.com/image/116384/dh_usrlocal%20%E5%AE%9E%E9%99%85%E4%B8%8A%E5%81%9A%E4%BA%86%E4%BB%80%E4%B9%88.png)
这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 软件包质量保证的一个主要因素。