Shell не дает подсказки, если автоматическое завершение включено (мерцающий курсор вместо этого)

Я пытался включить автозавершение оболочки, не комментируя следующие строки в моем .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

Однако это имеет побочный эффект. Даже при том, что автоматическое заполнение, кажется, работает, когда я открываю новый терминал, только мерцающий курсор представлен:

enter image description here

Я возвращаюсь к обычному user@machine:~$ запросите только после нажатия Ctrl+C.

Нормальное поведение восстанавливается, если я комментирую вышеупомянутые строки (но никакое автозавершение еще).

Я не могу выяснить, какова проблема.

- Обновление 1--

Вот то, что делает код:

enter image description here

- Обновление 2--

Вот вывод предложенных команд. Somethings сохраняет цикличное выполнение, и терминал лавинно рассылается 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 ]]

- Обновление 3--

Вот требуемый вывод:

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

Действительно последняя строка показывает то, что Вы предсказали. Но я не знаю, что сделать с тем файлом: я должен удалить его, или я по ошибке перезаписал его? Если так, что оригинал был доволен?

4
задан 21 August 2014 в 18:48

2 ответа

Тот факт, что вывод, который вы получаете с помощью set -x, содержит так много знаков плюс (++++++), означает, что / usr / share / bash-завершении / bash_completion рекурсивно рекурсивно. 1125]

Другими словами, / usr / share / bash-завершению / bash_completion сам «вызывает», что приводит к возникновению своего рода бесконечного цикла, как вы заметили.

На вашем месте я бы проверил /etc/bash_completion.d в поисках ссылок на / usr / share / bash-завершении / bash_completion . В частности, вот что я хотел бы сделать:

  1. ls -l /etc/bash_completion.d (не должно быть символических ссылок на / usr / share / bash-завершении / bash_completion );
  2. [ 1123] grep -r bash_completion /etc/bash_completion.d (ни один из файлов в /etc/bash_completion.d не должен иметь источник / usr / share / bash-завершению / bash_completion ).

В качестве альтернативы, вы можете запустить эти две команды в своей оболочке (конечно, без включения завершения bash):

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

Это напечатает все «импорт» и поможет нам идентифицировать неприятную кусок кода, который вызывает проблему.


Из вывода grep -r bash_completion /etc/bash_completion.d вы можете увидеть много совпадений. Большинство из них являются комментариями (потому что они начинаются с #), но есть интересная строка:

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

/etc/bash_completion.d/bash_completion~ является виновником. Это файл, который вызывает рекурсивный источник.

/ usr / share / bash-complete / bash_completion фактически автоматически получает каждый файл в каталоге /etc/bash_completion.d . Но этот каталог, в вашем случае, содержит файл bash_completion ~ , который снова запрашивает / usr / share / bash-завершении / bash_completion . Это приводит к петле, которую вы испытываете.

Итак, удалите его!

sudo rm /etc/bash_completion.d/bash_completion~

(Или, возможно, прочитайте его, если считаете, что оно содержит что-то полезное.)

Я не могу сказать вам, почему этот файл был в этом каталоге , Я могу вам сказать, что суффикс ~ означает, что это резервный файл. Многие текстовые редакторы (включая Gedit) создают резервные копии при сохранении. Вероятно, он был оставлен там по ошибке, когда вы вносили изменения.

3
ответ дан 17 November 2019 в 14:16

Ради отладки Вы могли добавить [приблизительно 113] строки, чтобы видеть, как далеко через код это добирается. Я предполагаю, что это повреждается в какой-то момент там, но это просто не делает его очень громко.

Замена это с чем-то вроде этого:

 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

В идеальном мире Вы будете видеть:

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

, Если это становится пойманным в bash_completion сценарии, включите отладку и получите его вручную (это предполагает, что Ваш терминал все еще работает):

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

, Который должен произвести до точки, которую это повреждает (или выходы) и это должно дать Вам другой индикатор для того, какова фактическая проблема.

3
ответ дан 17 November 2019 в 14:16

Другие вопросы по тегам:

Похожие вопросы: