Score:3

Bash completion not working in subshell

bo flag

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
Bodo avatar
pt flag
Which file defines the completion? Some files are only executed in interactive login shells. See https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html Please [edit] your question to add requested information or clarification.
terdon avatar
cn flag
@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.
Score:3
bo flag

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).

terdon avatar
cn flag
Have you changed the `/etc/bssh.bashrc` file and removed the line that reads the profile files?
PieterV avatar
bo flag
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.
terdon avatar
cn flag
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.
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.