#713051 bash: in /etc/skel/.bashrc, check if bash_completion has already run before

Package:
bash
Source:
bash
Description:
GNU Bourne Again SHell
Submitter:
Date:
2026-08-26 06:43:02 UTC
Severity:
minor
#713051#5
Date:
2013-06-22 07:18:24 UTC
From:
To:
Dear Maintainer,

By default, bash ships with bash_completion
disabled in /etc/bash.bashrc,
enabled in /etc/skel/.bashrc

If, when, an administrator decides to uncomment (enable) bash_completion in
bash.bashrc,
the script runs twice for users with unmodified .bashrc.

If a test is added to /etc/skel/.bashrc, like so:
if [ ! $BASH_COMPLETION_COMPAT_DIR ]; then
    #... whole of bash_completion code
fi

The script doesn't run twice.

$ time [ ! $BASH_COMPLETION_COMPAT_DIR ] && . /etc/bash_completion

real    0m0.000s
user    0m0.000s
sys     0m0.000s

$ time . /etc/bash_completion

real    0m0.187s
user    0m0.092s
sys    0m0.024s

It's a sane proposed default.

#713051#10
Date:
2017-03-20 13:57:19 UTC
From:
To:
This bug report is correct, however, the situation is a little more
complicated.

/etc/profile.d/bash_completion.sh already contains code that checks whether
bash_completion has already run. Hence, there should be no need to uncomment
the code in /etc/bash.bashrc.

However, /etc/profile.d/bash_completion.sh does not load bash_completion if
the current bash is non-interactive. Thus, it depends how your login shell
is set up whether bash_completion is loaded at this stage or not: in a
console login it is loaded, whereas at least on my systemd/GNOME
combination, it is not (it was previously loaded when upstart was in charge
rather than systemd).

It would be nice to simplify the setup. Fortunately, it only involves two
packages: bash supplies /etc/bash.bashrc and /etc/skel/.bashrc, and
bash-completion supplies /etc/profile.d/bash_completion.sh.

This file /etc/profile.d/bash_completion.sh does everything that is
required: it checks that the bash running is new enough, that it is being
run interactively, and that bash_completion has not already been run.

Therefore, it seems to me the logical thing to do is always to call this
file.

Hence, the simplest fix seems to me to replace the code in /etc/bash.bashrc
and in /etc/skel/.bashrc with something like the following (I give the
/etc/skel version, where the code is uncommented, and have added a phrase to
the comment to note that it may not run from /etc/profile):

# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc in an interactive shell).
if [ -f /etc/profile.d/bash_completion.sh ]; then
    . /etc/profile.d/bash-completion.sh
fi

This has another advantage: it also checks for user-overridden
bash_completion in XDG_CONFIG_HOME.

As a consequence, the script should arguably be moved to
/usr/share/bash-completion and suitably renamed, but that’s a matter for the
bash-completion package.


There is another question which is a matter for the bash-completion package:
since bash-completion is only useful in interactive shells, why not remove
the /etc/profile script? The current default is to have the code commented
out in /etc/bash.bashrc, which is fine, because, as I observed above, the
default systemd/GNOME combination won’t run it anyway, and to have
bash_completion loaded by default in .bashrc, which again is fine, because
it’s needed there, and also desirable.

If this simplification is not adopted, then the comment above should be
expanded to mention /etc/profile.d/bash_completion, as otherwise users
administering their own machines may be confused that, for example in a
console login, bash-completion is active even if disabled in both ~/.bashrc
and /etc/bash.bashrc.

#713051#15
Date:
2026-08-26 06:40:37 UTC
From:
To:
Though I'm using the latest stable, I inspected the contents of the
above package version from sid to confirm the same situation exists.

The bash_completion script will run twice by default in login shells,
like via SSH or inside tmux, though only once in others such as those
spawned by qterminal. This can be verified with a simple script at
/etc/bash_completion.d/test containing:

echo test sourced${_test_completion_loaded+' again'} >&2
_test_completion_loaded=yes

The problem is that /etc/bash.bashrc comments out the sourcing of the
completion script in the "if ! shopt -oq posix; then" block, then the
/etc/profile loads it anyway (via /etc/profile.d/bash_completion.sh).
The profile route is guarded against double inclusion but normally
this guard is unused, then the user's .bashrc (by default from
/etc/skel/.bashrc) uses the same unguarded code that /etc/bash.bashrc
contains, and so it's sourced a second time. I thought this could be
so users can opt out of completion by commenting out only their own
.bashrc's sourcing. However, this only works for shells that don't use
the profile route.

On Ubuntu, the commenting of the unguarded loads in /etc/bash.bashrc
and skel is reversed. So /etc/bash.bash does load completion, the
profile's guarded load short circuits, the skel file won't, and it
loads only once regardless of how the shell is invoked. This seems
like a better choice because the profile route including completion
(in both distros) implies it should be enabled system-wide.

Debian's wiki page (https://wiki.debian.org/Add%20Bash%20Completion)
recommends the /etc/bash_completion.d/ option for adding completions
to the whole system that aren't from packages, so anything in there
runs twice for every shell, but should really be lazy-loaded from
/usr/local/share/bash-completion/completions/

I agree that automatic load should be guarded against double-sourcing,
but manual re-sourcing should be possible, so the guard cannot be
within the bash_completion script itself. Loading via
/etc/profile.d/bash_completion.sh always, as Reuben suggsted or
swapping the comments would at least fix the default. The problem then
becomes how to migrate existing users that have an unguarded load in
their .bashrc.

Whatever the solution, the problem exists on an unmodified system.
Debian should not be running things twice nor recommending eager
loading.