4

I tryed to enable shell autocompletion uncommenting the following lines in my .bashrc:

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

However, this have a side effect. Even though autocomplete seems to work, when I open a new terminal, only a blinking cursor is presented:

enter image description here

I am returned to the usual user@machine:~$ prompt only after pressing Ctrl+C.

The normal behavior is restored if I comment the above lines (but no autocompletion any more).

I can't figure out what the problem is.

--Update 1--

Here's what the code does:

enter image description here

--Update 2--

Here's the output of the suggested commands. Somethings keeps looping and the terminal is flooded by the ouptut.

++++++ : /etc/bash_completion.d
++++++ readonly BASH_COMPLETION_COMPAT_DIR
++++++ _blacklist_glob='@(acroread.sh)'
++++++ shopt -s extglob progcomp
++++++ complete -d pushd
++++++ complete -u write chfn groups slay w sux runuser
++++++ complete -A stopped -P '"%' -S '"' bg
++++++ complete -j -P '"%' -S '"' fg jobs disown
++++++ complete -v readonly unset
++++++ complete -A setopt set
++++++ complete -A shopt shopt
++++++ complete -A helptopic help
++++++ complete -a unalias
++++++ complete -A binding bind
++++++ complete -c command type which
++++++ complete -b builtin
++++++ [[ linux-gnu == *@(solaris|aix)* ]]
++++++ [[ linux-gnu == *@(solaris|aix)* ]]
++++++ [[ linux-gnu == *@(solaris|aix)* ]]
++++++ _backup_glob='@(#*#|*@(~|.@(bak|orig|rej|swp|dpkg*|rpm@(orig|new|save))))'
++++++ complete -F _service service
++++++ _sysvdirs
++++++ sysvdirs=()
++++++ [[ -d /etc/rc.d/init.d ]]
++++++ [[ -d /etc/init.d ]]
++++++ sysvdirs+=(/etc/init.d)
++++++ [[ -f /etc/slackware-version ]]
++++++ for svcdir in '${sysvdirs[@]}'
++++++ for svc in '$svcdir/!($_backup_glob)'
++++++ [[ -x /etc/init.d/acpid ]]
++++++ complete -F _service /etc/init.d/acpid
++++++ for svc in '$svcdir/!($_backup_glob)'
++++++ [[ -x /etc/init.d/anacron ]]
++++++ complete -F _service /etc/init.d/anacron
++++++ for svc in '$svcdir/!($_backup_glob)'
++++++ [[ -x /etc/init.d/apparmor ]]

--Update 3--

Here's the requested output:

ac@ac:~$ grep -r bash_completion /etc/bash_completion.d
/etc/bash_completion.d/bash.bashrc:#  if [ -f /usr/share/bash-completion/bash_completion ]; then
/etc/bash_completion.d/bash.bashrc:#    . /usr/share/bash-completion/bash_completion
/etc/bash_completion.d/bash.bashrc:#  elif [ -f /etc/bash_completion ]; then
/etc/bash_completion.d/bash.bashrc:#    . /etc/bash_completion
/etc/bash_completion.d/bash.bashrc.bak:#  if [ -f /usr/share/bash-completion/bash_completion ]; then
/etc/bash_completion.d/bash.bashrc.bak:#    . /usr/share/bash-completion/bash_completion
/etc/bash_completion.d/bash.bashrc.bak:#  elif [ -f /etc/bash_completion ]; then
/etc/bash_completion.d/bash.bashrc.bak:#    . /etc/bash_completion
/etc/bash_completion.d/inkscape:# put this file in /etc/bash_completion.d/ 
/etc/bash_completion.d/desktop-file-validate:# put this file in /etc/bash_completion.d/
/etc/bash_completion.d/bash_completion~:. /usr/share/bash-completion/bash_completion
/etc/bash_completion.d/git-completion.bash:#   bash_completion - programmable completion functions for bash 3.2+
/etc/bash_completion.d/libreoffice.sh:# Programmable bash_completion file for the main office applications
/etc/bash_completion.d/bash_completion:# . /usr/share/bash-completion/bash_completion

Indeed the last line shows what you predicted. But I don't know what to do with that file: should I delete it, or I mistakenly overwrote it? If so, what was the original content?

3
  • As the comment says, have you checked to see if it's enabled in /etc/bash.bashrc? I believe it is by default. – saiarcot895 Aug 6 '14 at 14:52
  • Yes, I double checked the comments. If I uncomment the same lines in /etc/bash.bashrc I get the same problem. At this moment, the lines are commented in both files, and the shell starts normally (no autocompletion, though). – Alessandro Cuttin Aug 6 '14 at 15:09
  • What terminal emulator are you using? It might also benefit to upload/pastebin your /usr/share/bash-completion/bash_completion and we can diff it to see if it's been modified in any way. just fyi my .bashrc doesn't even try sourcing /usr/share/bash-completion/bash_completion that is handled by /etc/bash_completion – ElefantPhace Aug 20 '14 at 23:35
3
+100

The fact that the output you get with set -x contains so many plus signs (++++++) means that /usr/share/bash-completion/bash_completion is being re-sourced recursively.

In other words, /usr/share/bash-completion/bash_completion is "calling" himself, resulting in a sort of infinite loop, as you noted.

If I were you, I would check /etc/bash_completion.d looking for references to /usr/share/bash-completion/bash_completion. Specifically, here is what I would do:

  1. ls -l /etc/bash_completion.d (there must be no symlinks to /usr/share/bash-completion/bash_completion);
  2. grep -r bash_completion /etc/bash_completion.d (none of the files in /etc/bash_completion.d should source /usr/share/bash-completion/bash_completion).

Alternatively, you can run these two commands in your shell (without bash completion enabled, of course):

set -x
. /usr/share/bash-completion/bash_completion |& grep -E "^\++ (\.|source)"

This will print all "imports" and will help us identify the nasty piece of code that is causing the problem.


From the output of grep -r bash_completion /etc/bash_completion.d you can see many matches. Most of them are comments (because they start with #), but there's an interesting line:

/etc/bash_completion.d/bash_completion~:. /usr/share/bash-completion/bash_completion

/etc/bash_completion.d/bash_completion~ is the culprit. This is the file that is causing the recoursive re-source.

/usr/share/bash-completion/bash_completion in fact automatically sources every file in the /etc/bash_completion.d directory. But this directory, in your case, contains the bash_completion~ file, which is sourcing /usr/share/bash-completion/bash_completion again. This results in the sort of loop that you are experiencing.

So go ahead and delete it!

sudo rm /etc/bash_completion.d/bash_completion~

(Or maybe read it if you believe it contains something useful.)

I cannot tell you why that file was in that directory. What I can tell you is that the suffix ~ means that this is a backup file. Many text editors (including Gedit) create backup copies upon saving. Probably it was left there by mistake while you were making changes.

4
  • I would also check for ../bash_completion (referring to the file /etc/bash_completion) to make sure the scripts aren't calling the file that sources the Bash completion script. – saiarcot895 Aug 19 '14 at 12:18
  • @saiarcot895: I modified the grep based on your suggestion. – Andrea Corbellini Aug 19 '14 at 12:22
  • thanks for the answer! I don't have time right now to check, but I'll try to do that before the bounty expires ;) – Alessandro Cuttin Aug 19 '14 at 15:34
  • See update number 3: you were right! – Alessandro Cuttin Aug 21 '14 at 14:49
3

For the sake of debugging you could add some echo lines to see how far through the code it gets. I'm assuming it's breaking at some point in there but it's just not doing it very loudly.

Replace it with something like this:

 if ! shopt -oq posix; then
   echo Entering bash-completion load
   if [ -f /usr/share/bash-completion/bash_completion ]; then
     echo Sourcing /usr/share/bash-completion/bash_completion
     . /usr/share/bash-completion/bash_completion
     echo Sourced
   elif [ -f /etc/bash_completion ]; then
     echo Sourcing /etc/bash_completion
     . /etc/bash_completion
     echo Sourced
   fi
 fi
 echo Done

In an ideal world you'll see:

Entering bash-completion load
Sourcing /usr/share/bash-completion/bash_completion
Sourced
Done

If it's getting caught in the bash_completion script, turn debug on and source it manually (this is assuming your terminal still works):

set -x
. /usr/share/bash-completion/bash_completion

That should output up to the point it breaks (or exits) and that should give you another indicator for what the actual problem is.

3
  • @AlessandroCuttin I've updated mine too. – Oli Aug 6 '14 at 16:21
  • What do you mean with "turn debug on"? – Alessandro Cuttin Aug 6 '14 at 18:53
  • Question updated, I don't know if it's what you asked for – Alessandro Cuttin Aug 7 '14 at 8:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.