Skip to content

RPM installs into /usr/local/bin/ #377

Closed

Description

@jccleaver

Describe the bug

gh is installed into /usr/local/bin/gh when installed via RPM. It should be in /usr/bin/ instead. Among other things, this ensures that the command is in the normal $PATH.

Steps to reproduce the behavior

[root@localhost ~]# rpm -qa gh
gh-0.5.4-1.x86_64
[root@localhost ~]# rpm -ql gh
/usr/local/bin/gh

Expected vs actual behavior

Package-installed software should not be installed into /usr/local/ as that's for local admin use (more specifically, locally compiled and installed items). Packages should install in regular system directories.

Activity

  1. mbailey commented on Jun 17, 2022

    @mbailey

    Package-installed software should not be installed into /usr/local/ as that's for local admin use (more specifically, locally compiled and installed items). Packages should install in regular system directories.

    I believe this is incorrect.

    The Linux FHS spec 3.0 states:

    "The /usr/local hierarchy is for use by the system administrator when installing software locally. It needs to be safe from being overwritten when the system software is updated."

    and

    "Software placed in / or /usr may be overwritten by system upgrades (though we recommend that distributions do not overwrite data in /etc under these circumstances). For this reason, local software must not be placed outside of /usr/local without good reason."

    Does a "normal $PATH" exist that does not include /usr/local/bin? I don't recall ever having to manually add it.

    Can this issue be reopened @mislav ? I suspect github influences the choices of other developers.

  2. mislav commented on Jun 20, 2022

    @mislav
    Contributor

    @mbailey Our RPM installs nothing to /usr/local:

    $ rpm2cpio ./gh_2.12.1_linux_amd64.rpm | cpio -idmv
    /usr/bin/gh
    /usr/share/man/man1/gh-alias-delete.1
    /usr/share/man/man1/gh-alias-list.1
    /usr/share/man/man1/gh-alias-set.1
    /usr/share/man/man1/gh-alias.1
    /usr/share/man/man1/gh-api.1
    /usr/share/man/man1/gh-auth-login.1
    /usr/share/man/man1/gh-auth-logout.1
    /usr/share/man/man1/gh-auth-refresh.1
    /usr/share/man/man1/gh-auth-setup-git.1
    /usr/share/man/man1/gh-auth-status.1
    /usr/share/man/man1/gh-auth.1
    /usr/share/man/man1/gh-browse.1
    /usr/share/man/man1/gh-codespace-code.1
    /usr/share/man/man1/gh-codespace-cp.1
    /usr/share/man/man1/gh-codespace-create.1
    /usr/share/man/man1/gh-codespace-delete.1
    /usr/share/man/man1/gh-codespace-edit.1
    /usr/share/man/man1/gh-codespace-jupyter.1
    /usr/share/man/man1/gh-codespace-list.1
    /usr/share/man/man1/gh-codespace-logs.1
    /usr/share/man/man1/gh-codespace-ports-forward.1
    /usr/share/man/man1/gh-codespace-ports-visibility.1
    /usr/share/man/man1/gh-codespace-ports.1
    /usr/share/man/man1/gh-codespace-ssh.1
    /usr/share/man/man1/gh-codespace-stop.1
    /usr/share/man/man1/gh-codespace.1
    /usr/share/man/man1/gh-completion.1
    /usr/share/man/man1/gh-config-get.1
    /usr/share/man/man1/gh-config-list.1
    /usr/share/man/man1/gh-config-set.1
    /usr/share/man/man1/gh-config.1
    /usr/share/man/man1/gh-extension-create.1
    /usr/share/man/man1/gh-extension-exec.1
    /usr/share/man/man1/gh-extension-install.1
    /usr/share/man/man1/gh-extension-list.1
    /usr/share/man/man1/gh-extension-remove.1
    /usr/share/man/man1/gh-extension-upgrade.1
    /usr/share/man/man1/gh-extension.1
    /usr/share/man/man1/gh-gist-clone.1
    /usr/share/man/man1/gh-gist-create.1
    /usr/share/man/man1/gh-gist-delete.1
    /usr/share/man/man1/gh-gist-edit.1
    /usr/share/man/man1/gh-gist-list.1
    /usr/share/man/man1/gh-gist-view.1
    /usr/share/man/man1/gh-gist.1
    /usr/share/man/man1/gh-gpg-key-add.1
    /usr/share/man/man1/gh-gpg-key-list.1
    /usr/share/man/man1/gh-gpg-key.1
    /usr/share/man/man1/gh-issue-close.1
    /usr/share/man/man1/gh-issue-comment.1
    /usr/share/man/man1/gh-issue-create.1
    /usr/share/man/man1/gh-issue-delete.1
    /usr/share/man/man1/gh-issue-edit.1
    /usr/share/man/man1/gh-issue-list.1
    /usr/share/man/man1/gh-issue-reopen.1
    /usr/share/man/man1/gh-issue-status.1
    /usr/share/man/man1/gh-issue-transfer.1
    /usr/share/man/man1/gh-issue-view.1
    /usr/share/man/man1/gh-issue.1
    /usr/share/man/man1/gh-label-clone.1
    /usr/share/man/man1/gh-label-create.1
    /usr/share/man/man1/gh-label-delete.1
    /usr/share/man/man1/gh-label-edit.1
    /usr/share/man/man1/gh-label-list.1
    /usr/share/man/man1/gh-label.1
    /usr/share/man/man1/gh-pr-checkout.1
    /usr/share/man/man1/gh-pr-checks.1
    /usr/share/man/man1/gh-pr-close.1
    /usr/share/man/man1/gh-pr-comment.1
    /usr/share/man/man1/gh-pr-create.1
    /usr/share/man/man1/gh-pr-diff.1
    /usr/share/man/man1/gh-pr-edit.1
    /usr/share/man/man1/gh-pr-list.1
    /usr/share/man/man1/gh-pr-merge.1
    /usr/share/man/man1/gh-pr-ready.1
    /usr/share/man/man1/gh-pr-reopen.1
    /usr/share/man/man1/gh-pr-review.1
    /usr/share/man/man1/gh-pr-status.1
    /usr/share/man/man1/gh-pr-view.1
    /usr/share/man/man1/gh-pr.1
    /usr/share/man/man1/gh-release-create.1
    /usr/share/man/man1/gh-release-delete-asset.1
    /usr/share/man/man1/gh-release-delete.1
    /usr/share/man/man1/gh-release-download.1
    /usr/share/man/man1/gh-release-edit.1
    /usr/share/man/man1/gh-release-list.1
    /usr/share/man/man1/gh-release-upload.1
    /usr/share/man/man1/gh-release-view.1
    /usr/share/man/man1/gh-release.1
    /usr/share/man/man1/gh-repo-archive.1
    /usr/share/man/man1/gh-repo-clone.1
    /usr/share/man/man1/gh-repo-create.1
    /usr/share/man/man1/gh-repo-delete.1
    /usr/share/man/man1/gh-repo-deploy-key-add.1
    /usr/share/man/man1/gh-repo-deploy-key-delete.1
    /usr/share/man/man1/gh-repo-deploy-key-list.1
    /usr/share/man/man1/gh-repo-deploy-key.1
    /usr/share/man/man1/gh-repo-edit.1
    /usr/share/man/man1/gh-repo-fork.1
    /usr/share/man/man1/gh-repo-list.1
    /usr/share/man/man1/gh-repo-rename.1
    /usr/share/man/man1/gh-repo-sync.1
    /usr/share/man/man1/gh-repo-view.1
    /usr/share/man/man1/gh-repo.1
    /usr/share/man/man1/gh-run-cancel.1
    /usr/share/man/man1/gh-run-download.1
    /usr/share/man/man1/gh-run-list.1
    /usr/share/man/man1/gh-run-rerun.1
    /usr/share/man/man1/gh-run-view.1
    /usr/share/man/man1/gh-run-watch.1
    /usr/share/man/man1/gh-run.1
    /usr/share/man/man1/gh-search-issues.1
    /usr/share/man/man1/gh-search-prs.1
    /usr/share/man/man1/gh-search-repos.1
    /usr/share/man/man1/gh-search.1
    /usr/share/man/man1/gh-secret-delete.1
    /usr/share/man/man1/gh-secret-list.1
    /usr/share/man/man1/gh-secret-set.1
    /usr/share/man/man1/gh-secret.1
    /usr/share/man/man1/gh-ssh-key-add.1
    /usr/share/man/man1/gh-ssh-key-list.1
    /usr/share/man/man1/gh-ssh-key.1
    /usr/share/man/man1/gh-status.1
    /usr/share/man/man1/gh-workflow-disable.1
    /usr/share/man/man1/gh-workflow-enable.1
    /usr/share/man/man1/gh-workflow-list.1
    /usr/share/man/man1/gh-workflow-run.1
    /usr/share/man/man1/gh-workflow-view.1
    /usr/share/man/man1/gh-workflow.1
    /usr/share/man/man1/gh.1
    67586 blocks
    

    Update: Oh I just realized that you were advocating for the reverse: that our RPM installs into /usr/local. Is that common practice for RPMs?

  3. mbailey commented on Jun 20, 2022

    @mbailey

    Update: Oh I just realized that you were advocating for the reverse: that our RPM installs into /usr/local. Is that common practice for RPMs?

    The references I included above explain that local software should not be deployed outside of /usr/local without good reason (because distro may overwrite).

    I checked the Makefile for a couple of projects (openssh, vim) and they default to deploying to /usr/local/bin.

    openssh
    # Makefile
    prefix=/usr/local
    exec_prefix=${prefix}
    bindir=${exec_prefix}/bin
    sbindir=${exec_prefix}/sbin

    vim
    # src/Makefile
    # 5. "make install" {{{1
    # If the new Vim seems to be working OK you can install it and the
    # documentation in the appropriate location. The default is
    # "/usr/local". Change "prefix" below to change the location.

    I originally read about the purpose of /usr/local in a blog post by Dan Benjamin from 2007.

  4. mislav commented on Jun 20, 2022

    @mislav
    Contributor

    @mbailey Thanks for elaborating. Makefiles of software you compile locally are one thing and I agree that they have /usr/local as default target, but we are talking about RPMs that you pull from remote package repositories. I'm not sure if that software is also considered "local" and, since it's managed by the system package manager, it makes sense to me that it's installed in /usr and not /usr/local. Note that I'm not a Linux expert of any kind.

  5. mbailey commented on Jun 20, 2022

    @mbailey

    Makefiles of software you compile locally are one thing and I agree that they have /usr/local as default target, but we are talking about RPMs that you pull from remote package repositories.

    That's a good distinction to make.

    I suspect the right answer is /usr/local for installs that aren't from the linux distribution but it would be good to know:

    • whether the Linux FHS has anything that would answer this question
    • what convention is being followed by other packages being hosted by 3rd parties

    I'll dig further

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions