Comment 5 for bug 1173728

Revision history for this message
Peter Cordes (peter-cordes) wrote : Re: bash programmable completion not loaded by default

As discussed in bug 790043 (about the slowdown of loading completions), the out-of-the-box configuration seems to be to load programmable completions (progcomp) for login shells, but not for non-login shells (e.g. bash in an xterm).

TL:DR summary: ~/.bashrc should source /etc/profile.d/bash_completion.sh

 This is mind-bogglingly silly, and would be confusing except that desktop users pretty much never run a login shell ever. Only with sudo --login, probably, or if they happen to configure gnome-terminal to start a login shell. People logging in with ssh to an Ubuntu machine will get progcomp in their login shell, but not in subshells they start inside screen(1), for example.

 The out-of-the-box shipped /etc/profile is
trusty: http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/base-files/trusty/view/head:/share/profile
vivid-proposed: http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/vivid/base-files/vivid-proposed/view/head:/share/profile

The out-of-the-box /etc/bash.bashrc is:
trusty-updates: http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/bash/trusty-updates/view/head:/debian/etc.bash.bashrc
vivid-proposed: http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/vivid/bash/vivid-proposed/view/head:/debian/etc.bash.bashrc

The out-of-the-box /etc/skel/.bashrc is:
vivid-proposed: http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/vivid/base-files/vivid-proposed/view/head:/share/dot.bashrc

All this adds up to (in order of action for a login shell):
/etc/profile.d/bash_completion.sh : (from /etc/profile) source progcomp after checking it it's already loaded
~/.profile : nothing
-- Non-login shells start here
/etc/bash.bashrc : commented-out sourcing of progcomp (no check for already loaded)
~/.bashrc (from /etc/skel/.bashrc at adduser time): commented-out sourcing of progcomp (no check for already loaded)

In a login shell, /etc/profile sources /etc/bash.bashrc, and the default ~/.profile sources ~/.bashrc. (In both cases, after checking that the shell is bash). So login shells get everything that non-login shells do, plus whatever you put in profile to do once-per-login things, and/or to set env vars (which are inherited by non-login shells, and so don't need to be set again for every non-login shell.)

 My vote is to have ~/.bashrc source /etc/profile.d/bash_completion.sh (checking only that it exists, to not clutter up the user's file, because that file checks if bash_completion was already loaded.)

 There are mechanisms to check if bash_completion has already been sourced, so we can avoid taking the speed-hit of doing it twice. Any system rc file should check first before sourcing, because having bash_completion itself refuse to be re-sourced is problematic. (what if a user wants to do it manually?)

/etc/profile.d/bash_completion.sh (shipped by bash-completion) checks on -z "$BASH_COMPLETION_COMPAT_DIR", which the giant bash_completion script defines (and makes readonly, meaning it can't ever be unset). So I guess BASH_COMPLETION_COMPAT_DIR is the canonical way to check if it's already loaded.

 A better check might be if ! complete -p paste > /dev/null; then source it; fi, because upstream hopes to eventually get rid of /etc/bash_completion.d. But it will probably never happen.

 None of this helps if profile.d goes first, and then a user's ~/.bashrc sources completions without checking, though. That's why I vote for modifying /etc/skel/.bashrc, rather than adding it by default to /etc/bash.bashrc. It can't result in extra sourcing of completions for existing installs, because it's just the template for new accounts.

 Also, if /etc/bash.bash sources it, then admin users can't avoid the performance hit of having it load.

 I think the default ~/.bashrc is a really obvious place to put the default setting for a bash-specific shell feature that individual users might want to config differently.

 It's also not going to change anything for people upgrading existing installs that already work the way they like. All we lose out on is giving progcomp to people who didn't even know it existed, when they upgrade. Any way to do that has downsides that I think are worth avoiding for the long term. Except by writing a tool to check if the users is missing out on progcomp for non-login shells, and ask them if they want to enable it, and then tack lines on to their ~/.bashrc. I know do-release-upgrade runs helper scripts that help deal with changes, would that be an appropriate place to put that kind of check? Or should it not be touching anything under /home?