4

When I start a bash subshell (by calling bash from my command prompt), all tab completion stops working. The complete command becomes empty in the new shell:

$ complete
[...]
complete -F _apport-collect apport-collect
complete -F _filedir_xspec vim
complete -o dirnames -o filenames -F _apport-bug ubuntu-bug
complete -F _known_hosts ftp
complete -F _longopt units
complete -F _longopt uname
complete -F _service /etc/init.d/network-manager
complete -F _longopt touch
complete -F _longopt ldd
complete -F _command then
complete -F _known_hosts rlogin
complete -F _service /etc/init.d/sddm
complete -F _service /etc/init.d/lvm2-lvmpolld
complete -F _command command
complete -F _longopt sha384sum
complete -F _known_hosts fping6
complete -F _longopt rm
complete -F _service /etc/init.d/cryptdisks
complete -F _service /etc/init.d/binfmt-support
$ bash
$ complete
$

How can I get tab completion to work in subshells as well? Am I missing something in my profile or bashrc?

Edit: the completions are present by default in ubuntu (not added by me). /etc/bash.bashrc mentions completions, but the section is commented out by default (not something I did):

# enable bash completion in interactive shells
#if ! shopt -oq posix; then
#  if [ -f /usr/share/bash-completion/bash_completion ]; then
#    . /usr/share/bash-completion/bash_completion
#  elif [ -f /etc/bash_completion ]; then
#    . /etc/bash_completion
#  fi
#fi

/etc/profile executes all scripts in /etc/profile.d, which does contain a script that loads completions:

# shellcheck shell=sh disable=SC1091,SC2039,SC2166
# Check for interactive bash and that we haven't already been sourced.
if [ "x${BASH_VERSION-}" != x -a "x${PS1-}" != x -a "x${BASH_COMPLETION_VERSINFO-}" = x ]; then

    # Check for recent enough version of bash.
    if [ "${BASH_VERSINFO[0]}" -gt 4 ] || \
       [ "${BASH_VERSINFO[0]}" -eq 4 -a "${BASH_VERSINFO[1]}" -ge 1 ]; then
        [ -r "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion" ] && \
            . "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion"
        if shopt -q progcomp && [ -r /usr/share/bash-completion/bash_completion ]; then
            # Source completion code.
            . /usr/share/bash-completion/bash_completion
        fi
    fi

fi

Both bash sessions seem to have been started with the same arguments:

$ complete
...
complete -F _service /etc/init.d/cryptdisks
complete -F _service /etc/init.d/binfmt-support
$ echo $-
himBHs
$ bash
$ complete
$ echo $-
himBHs

My bash command isn't aliased to anything:

$ type bash
bash is /usr/bin/bash
2
  • Which file defines the completion? Some files are only executed in interactive login shells. See gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html Please edit your question to add requested information or clarification.
    – Bodo
    Commented Jan 10, 2023 at 14:35
  • @Bodo this is standard functionality, on Ubuntu systems, I believe it is controlled by the file /etc/profile.d/bash_completion.sh which is sourced by the default /etc/bash.bashrc, a file that is read by interactive, non-login shells and login shells source the files in /etc/profile.d anyway. So it isn't a question of that.
    – terdon
    Commented Jan 10, 2023 at 14:55

1 Answer 1

5

It looks like the default completions are loaded by the /etc/profile (which in turn executes /etc/profile.d/bash_completion.sh). In non-login shells, however, /etc/profile is not executed, so the completions are not loaded.

If I start a login bash subshell, the completions are loaded:

$ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
Login shell
$ complete | wc -l
214
$ bash
$ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
Not login shell
$ complete | wc -l
0
$ exit
exit
$ bash --login
$ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
Login shell
$ complete | wc -l
214

So basically, I have to load the completions in non-login shells explicitly, as they are not loaded by default (at least not on my setup).

3
  • Have you changed the /etc/bssh.bashrc file and removed the line that reads the profile files?
    – terdon
    Commented Jan 11, 2023 at 9:34
  • I have not changed /etc/bash.bashrc, but by default it doesn't seem to include anything to read profile files. The line to enable bash completion are also commented out by default, but I could enable those of course.
    – PieterV
    Commented Jan 11, 2023 at 14:08
  • Oh, sorry, my bad. I was looking at an Ubuntu Server instance I have and I thought that the Ubuntu /etc/bash.bashrc was set to read profile but I was wrong. This is so weird though, it feels like a bug. Why in the world would the Ubuntu devs want to disable completion in login shells. This makes no sense to me. What's worse, I can't reproduce it. Even on that Ubuntu machine where the completion lines are commented out, I still have complete give output when starting a new non-login subshell. How odd.
    – terdon
    Commented Jan 11, 2023 at 14:15

You must log in to answer this question.

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