O shell não informa se a conclusão automática está ativada (cursor piscando)

4

Eu tentei ativar o preenchimento automático de shell removendo o comentário das seguintes linhas no meu .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

No entanto, isso tem um efeito colateral. Embora o preenchimento automático pareça funcionar, quando abro um novo terminal, apenas um cursor piscante é apresentado:

Eu retornei ao prompt usual user@machine:~$ somente depois de pressionar Ctrl+C .

O comportamento normal é restaurado se eu comentar as linhas acima (mas não a autocompletar mais).

Eu não consigo descobrir qual é o problema.

- Atualização 1 -

Veja o que o código faz:

- Atualização 2 -

Aqui está a saída dos comandos sugeridos. Algumas coisas continuam em loop e o terminal é inundado pela saída.

++++++ : /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 ]]

- Atualização 3 -

Aqui está a saída solicitada:

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

Na verdade, a última linha mostra o que você previu. Mas eu não sei o que fazer com esse arquivo: eu deveria deletá-lo, ou eu, erroneamente, o substituí? Se sim, qual foi o conteúdo original?

    
por Alessandro Cuttin 06.08.2014 / 16:48

2 respostas

3

O fato de a saída obtida com set -x conter tantos sinais de adição ( ++++++ ) significa que / usr / share / bash-completion / bash_completion está sendo recursivo.

Em outras palavras, / usr / share / bash-completion / bash_completion está "chamando" ele mesmo, resultando em uma espécie de loop infinito, como você observou.

Se eu fosse você, verificaria /etc/bash_completion.d procurando referências a / usr / share / bash-completion / bash_completion . Especificamente, aqui está o que eu faria:

  1. ls -l /etc/bash_completion.d (não deve haver links simbólicos para / usr / share / bash-completion / bash_completion );
  2. grep -r bash_completion /etc/bash_completion.d (nenhum dos arquivos em /etc/bash_completion.d deve fornecer / usr / share / bash-completion / bash_completion ).

Como alternativa, você pode executar esses dois comandos em seu shell (sem concluir o bash ativado, é claro):

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

Isso imprimirá todas as "importações" e nos ajudará a identificar o código desagradável que está causando o problema.

Da saída de grep -r bash_completion /etc/bash_completion.d , você pode ver muitas correspondências. A maioria deles são comentários (porque começam com # ), mas há uma linha interessante:

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

/etc/bash_completion.d/bash_completion~ é o culpado. Este é o arquivo que está causando o recurso recursivo.

/ usr / share / bash-completion / bash_completion , de fato, origina automaticamente todos os arquivos no diretório /etc/bash_completion.d . Mas este diretório, no seu caso, contém o arquivo bash_completion ~ , que está obtendo / usr / share / bash-completion / bash_completion novamente. Isso resulta no tipo de loop que você está experimentando.

Então, vá em frente e exclua-o!

sudo rm /etc/bash_completion.d/bash_completion~

(Ou talvez leia se você acredita que contém algo útil.)

Não sei dizer por que esse arquivo estava nesse diretório. O que posso dizer é que o sufixo ~ significa que este é um arquivo de backup. Muitos editores de texto (incluindo o Gedit) criam cópias de backup ao salvar. Provavelmente foi deixado lá por engano enquanto você estava fazendo mudanças.

    
por Andrea Corbellini 19.08.2014 / 14:12
3

Por uma questão de depuração, você pode adicionar algumas echo linhas para ver até onde o código é obtido. Eu estou supondo que está quebrando em algum momento, mas não está fazendo isso muito alto.

Substitua por algo assim:

 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

Em um mundo ideal, você verá:

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

Se ele estiver sendo capturado no script bash_completion, ative a depuração e faça a origem manualmente (isto supondo que o terminal ainda funcione):

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

Isso deve ser emitido até o ponto em que ele quebra (ou sai) e isso deve fornecer outro indicador do problema real.

    
por Oli 06.08.2014 / 18:01