The dh_usrlocal manpage sounds a bit cryptic to me:

It finds subdirectories of usr/local in the package build directory, and removes them, replacing them with maintainer script snippets (unless -n is used) to create the directories at install time, and remove them when the package is removed, in a manner compliant with Debian policy. These snippets are inserted into the maintainer scripts by dh_installdeb. See dh_installdeb(1) for an explanation of debhelper maintainer script snippets.

Mainainer scripts, snippets, -n... OK, but what is the purpose? Does it really just create (empty?) directories?

Can a kind soul explain it to me in a more practical way? Which part of policy I should read? Should I care if my app installs with PREFIX=/usr?


The purpose is to aid with policy compliance by that package. According to Debian policy (and, IIRC, the Filesystem Hierarchy Standard or FHS), official Debian packages are not permitted to own files or directories under /usr/local - that directory tree belongs to the local system administrator.

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

(bold emphasis added by me)

9.1.2. Site-specific programs

As mandated by the FHS, packages must not place any files in /usr/local, either by putting them in the file system archive to be unpacked by dpkg or by manipulating them in their maintainer scripts.

However, the package may create empty directories below /usr/local so that the system administrator knows where to place site-specific files. These are not directories in /usr/local, but are children of directories in /usr/local. These directories (/usr/local/*/dir/) should be removed on package removal if they are empty.

Note that this applies only to directories below /usr/local, not in /usr/local. Packages must not create sub-directories in the directory /usr/local itself, except those listed in FHS, section 4.5. However, you may create directories below them as you wish. You must not remove any of the directories listed in 4.5, even if you created them.

Since /usr/local can be mounted read-only from a remote server, these directories must be created and removed by the postinst and prerm maintainer scripts and not be included in the .deb archive. These scripts must not fail if either of these operations fail.

For example, the emacsen-common package could contain something like

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

in its postinst script, and

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

in the prerm script. (Note that this form is used to ensure that if the script is interrupted, the directory /usr/local/share/emacs will still be removed.)

If you do create a directory in /usr/local for local additions to a package, you should ensure that settings in /usr/local take precedence over the equivalents in /usr.

However, because /usr/local and its contents are for exclusive use of the local administrator, a package must not rely on the presence or absence of files or directories in /usr/local for normal operation.

The /usr/local directory itself and all the subdirectories created by the package should (by default) have permissions 2775 (group-writable and set-group-id) and be owned by root:staff.

See also https://wiki.debian.org/FilesystemHierarchyStandard

dh_usrlocal removes any such directories from the package and replaces them with code in the package scripts (the .postinst and .prerm scripts) to create/delete them at install/uninstall time, following the example given in the policy.

This may seem to make little practical difference because the directories are still created on install and deleted on uninstall, but Debian considers the failure of a package to comply with policy to be as serious a bug as any other - consistent and scrupulous adherence to policy is a major factor in quality assurance for Debian packages.

  • Neat. I think what confused me most was that I did not consider "system administrator" and "package maintainer" to be entirely different roles: a local admin might actually want to have packages for their /usr/local stuff (ca-certificates). By extension. I expected that no-usr-local be a weak rule, so I expected dh to somehow tolerate that, and thought dh_usrlocal somehow helps with this. Good to know how I was mistaken. :) – Alois Mahdal Aug 18 '17 at 3:50
  • 1
    @AloisMahdal when I was a sysad and made a package for ca certificates, I kept the certificate in /usr/share/.../... and copied it to /usr/local in postinst. It's particularly important that I didn't do stuff like put things in /usr/local/, since the old Ubuntu Software Centre complains about the quality of the package in such cases, making it harder to install for the average student who might need the CA certificate in a personal system. – muru Aug 18 '17 at 5:41
  • As "system administrator" on my machine, and install all "extra" stuff that I can't get via Debian packages, or where the Debian packages are not up-to-date, into /usr/local. That's mostly applications and libraries, compiled myself. So I appreciate it very much that no Debian packages mess with /usr/local, at all. – dirkt Aug 18 '17 at 6:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.