Как отладить и исправить медленное автозаполнение в Bash?

26

После недавнего обновления (Ubuntu 12.04 LTS) выполнение TAB в командной строке выполняется медленно. После ввода частичной команды (например evi [TAB]) или частичного имени файла (например evince somedocu[TAB]) оболочка, иногда, хотя и не всегда, зависает на несколько секунд.

Лично я предпочел бы менее мощное автозаполнение медленному. Есть ли простое исправление?

Изменить: Дополнительная информация, связанная с комментариями:

  • PATH довольно стандартный. ~ / bin содержит несколько скриптов bash

    $ echo $PATH
    /home/USERNAME/bin:/usr/local/bin:/usr/bin:/bin:/usr/games
  • Количество файлов в рабочем каталоге меньше 100.

  • Функция автозаполнения была особенно медленной после необычной активности диска (обновление системы). Таким образом, возможно, что перечитывание / usr / bin и других каталогов вызвало задержку.
январь
источник
4
не правда ли, что вы включаете управление скоростью жесткого диска с помощью обновления, и что автозаполнение ожидает, пока диск не проснется, чтобы вычислить автозаполнение?
Винсент Нивольерс
2
Зависит ли это от того, сколько файлов находится в вашем текущем каталоге?
Terdon
1
Что говорит # echo $ PATH? Если у вас есть много (несколько десятков тысяч или более) файлов в каталогах на вашем пути, это может быть причиной.
Стефан

Ответы:

28

Я не знаю, как починить - есть разные вещи, которые могут вызвать задержки. Но я могу предложить несколько советов для расследования.

Можно предположить, что где-то в пути поиска есть каталог ( $PATHили где-то, где bash ищет данные о завершении), который находится в файловой системе и медленно отвечает. Обычно это медленные удаленные файловые системы, но это также может быть неисправный жесткий диск, зависший драйвер FUSE и т. Д.

Первый шаг, который нужно изучить, - запустить set -xтрассировку команд, которые выполняет оболочка для генерации завершений. Смотрите, где он останавливается.

Если это не дает достаточно информации, принесите большие пушки. Обратите внимание на идентификатор процесса оболочки ( echo $$). Запустите в другом терминале strace -f -s9999 -p$$(или эквивалентно strace, если работаете в другом варианте Unix). Strace перечисляет системные вызовы, выполняемые процессом. Посмотрите, кажется ли, что он обращается к файлам, к которым он не должен, или же доступ к некоторым файлам медленный. Добавление параметра -Tв straceкомандную строку позволяет отображать время, затраченное на каждый системный вызов.

Жиль "ТАК - перестань быть злым"
источник
1
Сколько времени я использовал Unix и не знал set -x, какая классная команда. Очень "включенный хакерский режим"
Мэтт Флетчер
6
Ps, используйте, set +xчтобы вернуться к обычному режиму без отладки
Мэтт Флетчер
19

Если ваш * nix box настроен как клиент LDAP, у вас может быть эта проблема, даже если вы вошли как локальный пользователь.

Скучная информация отладки: Отладка с помощью set-x, я нашел завершение, которое висело в:

> set -x
> ls foo<tab>
...                     <--- lots of output removed
...
+ _quote_readline_by_ref foo quoted
+ '[' -z foo ']'
+ [[ foo == \'* ]]      <--- froze here
+ [[ foo == ~* ]]       <--- actually causing the trouble

Подтверждаю: я это подтвердил тем, ls ~*что тоже повесил Оказывается, мой ldap-сервер работал медленно, но это не должно влиять на такие вещи, как завершение bash и ls!

Решение: Ага, есть ошибка, связанная с bash-завершением + ldap, она будет исправлена ​​в более новой версии, и простой патч, если вы не хотите ждать. Заполнение вкладок снова быстро, ура!

Вот патч-файл на случай, если ссылка исчезнет. Он просто выходит за пределы строк 545 и 547:

--- /usr/share/bash-completion/bash_completion.orig 2014-11-06 10:36:14.981888369 +0100
+++ /usr/share/bash-completion/bash_completion  2014-11-06 10:36:25.142070963 +0100
@@ -542,9 +542,9 @@
     elif [[ $1 == \'* ]]; then
         # Leave out first character
         printf -v $2 %s "${1:1}"
-    elif [[ $1 == ~* ]]; then
+    elif [[ $1 == \~* ]]; then
         # avoid escaping first ~
-        printf -v $2 ~%q "${1:1}"
+        printf -v $2 \~%q "${1:1}"
     else
         printf -v $2 %q "$1"
     fi

Вам нужно выйти из текущей сессии ssh и повторно войти в систему, чтобы этот патч вступил в силу.

Джефф Уорд
источник
1
У меня была именно эта проблема, и патч хорош
Радман
2
Та же проблема здесь (Debian 8.5) 2 1/3 года назад, и решение работает как чудо. У Debian 8.6 нет проблем.
YoMismo
2
Я использовал set -xa миллион раз, но я никогда не ожидал, что он также покажет проблемы производительности завершения, большое спасибо!
МАРТ
Была эта проблема с Debian 9.8!
Филипп Гачу
0

Попробуй переустановить bash-завершение

sudo apt-get install --reinstall bash-completion

Для меня это исправлено в Ubuntu 18.04.3 LTS

arulraj.net
источник
0

Также некоторые люди используют дополнительные функции автозаполнения, такие как Git Bash Auto Complete . Замедление завершения bash может быть результатом неправильного поведения этих дополнительных функций автозавершения.

В моем случае это было автоматическое завершение Git bash, мой открытый ключ git был обновлен, поэтому он делал неудачную попытку аутентификации, вызывающую зависание. После того, как я удалил автозаполнение, снова было быстро. Поэтому я решил исправить свой ключ и снова включить его.

Николас ДиПьяцца
источник