13

I'm installing ripgrep on Ubuntu. It doesn't exist on the official repository or on private PPA's, so I'm following the project's instructions to install it as an out of tree package: https://github.com/BurntSushi/ripgrep#installation.

I managed to learn that these packages should live on /usr/local:

  • /usr/local/bin for binaries
  • /usr/local/share/doc/<package_name> for documentation
  • /usr/local/share/man for manual pages

What about bash completion? I understand that this is a little less standardized than those other categories and may be specific to each Bash installation. What is the way to do it in Ubuntu?

4
  • 1
    It appears to be installed in /etc/bash_completion.d/. Check /etc/bash.bashrc where that is loaded.
    – user232326
    Jan 10, 2018 at 21:03
  • But then it would be mixed with apt controlled packages... I was hoping for a separate path.
    – Spidey
    Jan 11, 2018 at 4:48
  • What does "out-of-tree" mean here? Do you just mean not delivered by a package manager? It seems "out-of-tree" is a term specific to the Linux kernel
    – huyz
    Sep 11, 2023 at 8:11
  • Yeah, I meant as outside of the distro's package manager repositories. I come from a Gentoo background where packages (ebuilds) are maintained in Git repos.
    – Spidey
    Sep 13, 2023 at 10:33

4 Answers 4

16

From what I could gather after a lot of reading, specially their official documentation, /usr/share/doc/bash-completion/README.Debian, and the sources themselves:

  • /etc/bash_completion.d/ is the legacy dir, where completions are eagerly loaded, i.e., all sourced at once when the main script runs. Only a few packages still install there, most already migrated to the new standard.

  • /usr/share/bash-completion/completions/ is the directory for completion files that are dynamically loaded on demand by bash-completion. They are only sourced when needed (and, most importantly, if needed), saving a ton of resources by not loading a bazillion completions for commands you'll never use.


Regarding this comment of yours about /etc:

it would be mixed with apt controlled packages... I was hoping for a separate path

Files at /etc are not exactly "apt controlled", at least not in the same way /usr/bin or /usr/share are.[1] They are configuration files, and they are meant to be modified by the local admin (you). Packages create them at install time, usually containing the default values, and then you're supposed to modify them to your needs.

Some packages go one step further to ease maintenance and instead of (or alongside) config files they also create an (empty) configuration directory for "drop-in", extra customization files. So instead of modifying a config file to change some settings, a difficult and error prone task using tools like grep, sed and awk, you just create (or delete) "configuration snippet" files that override the desired settings.

Take a look at all /etc/{,*/}*.d/ directories in your system. Does your package want to install a custom repository, like Google Chrome? Don't edit /etc/apt/sources.list, drop a file at /etc/apt/sources.list.d/. New services? /etc/systemd/system/. System settings? /etc/sysctl.d/ (btw, see its README).

Much much easier, and no more stepping in each other's toes.

Some dirs in /usr/share behave like this too: your .desktop file go to /usr/share/applications/, and new mimetypes to /usr/share/mime/packages/, and so on. The difference to /etc is, you, the admin, are not supposed to neither modify nor delete files that you didn't create/installed yourself.

And that's exactly the case with /usr/share/bash-completion/completions/.


That said, I have good news and bad news for you:

Bad news is... if you're tying to install the completion in their github repository, that's not a bash completion, but a zsh completion file! And no, bash and zsh are completely incompatible regarding completions.

Don't worry, because the good news is: ripgrep is available on apt repositories since Ubuntu 18.10! Yay! :D

sudo apt install ripgrep

And guess what? It contains a bash completion file! Installed, of course, at /usr/share/bash-completion/completions/rg.

Time to rejoice, pal!


[1]: To be honest, you could say they are "apt monitored", not controlled. Read Everything you need to know about conffiles: configuration files managed by dpkg for more details.

8

According to FAQ manual, you should just put the completion file in the ~/.local/share/bash-completion/completions/ generally in the case your own local completions. If that directory doesn't exist, you can make it using mkdir -p of course.

Put them in the completions subdir of $BASH_COMPLETION_USER_DIR (defaults to $XDG_DATA_HOME/bash-completion or ~/.local/share/bash-completion if $XDG_DATA_HOME is not set) to have them loaded automatically on demand when the respective command is being completed.

The file's name is meaningful.

The completion filename for command foo in this directory should be either foo, or foo.bash. (Underscore prefixed _foo works too, but is reserved for bash-completion internal use as a deprecation/fallback marker.)

2

The distro completion scripts generally load user completions if found. E.g. on Ubuntu, /etc/bash_completion sources /usr/share/bash-completion/bash_completion .. and that sources scripts from ~/.ssh/.. and ~/.bash_completion (which in my case sources ~/local/etc/bash_completion.d/*).

So if you have your ~/.bash_completion set up like that (see https://stackoverflow.com/a/12426672/274318 for a way to source all files in a directory), you can just install the ripgrep completions to your local completions dir.

2

I would like to add that, although largely undocumented, scripts in /usr/local/share/bash-completion/completions are also loaded. See this question. I also personally tested and verified with RHEL8 and Bash 4.4.20.

Therefore if you are locally installing software in /usr/local/bin, this is probably where you want to place your completion scripts (as opposed to /usr/share/bash-completion/completions, which is managed by your package manager).

This directory probably doesn't exist by default, so just create it:

mkdir -p /usr/local/share/bash-completion/completions

After putting your scripts in it and restarting your shell, your custom completions should work without needing extra configuration.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .