Почему завершение bash загружается так медленно на OS X?

16

Я не понимаю, почему завершение bash загружается так медленно на моем MacBook Pro.

Я сделал следующее в моем ~/.bash_profile:

echo "Loading BashCompletion..."
if [ -f /opt/local/etc/bash_completion ]; then
    . /opt/local/etc/bash_completion
fi
echo "BashCompletion loaded."

время выполнения bash_completion обычно составляет> 2 секунды.

Я нахожу это действительно раздражающим, когда я работаю над терминалом, который требует от меня постоянно открывать новые вкладки.

Есть ли способ, которым я могу кэшировать это или что-то?

(Обратите внимание, что я использую iTerm2, и это также медленно на оригинальном терминале в Mac).

disappearedng
источник
Этого не должно быть. Правильно ли вы используете завершение MacPort?
Slhck
Как выглядит загружаемый файл?
Даниэль Бек
@slhck: Да, я действительно использую завершение bash в Macport
исчезло
@Daniel: все хорошо, кроме этого. Я профилировал почти каждую линию.
исчезли
5
Я испытываю ту же медлительность, и я использую Homebrew.
Брайс

Ответы:

10

Краткая версия: удаление одной строки из /usr/local/etc/bash_completionсокращенного времени открытия новой вкладки с десяти секунд до четверти секунды. Продолжайте читать для деталей.

Я использую bash-complete из homebrew и столкнулся с той же проблемой. Загрузка скриптов завершения bash заняла более десяти секунд каждый раз, когда я открывал терминал.

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

При наличии have()функции по умолчанию и всех предоставленных сценариев завершения bash для загрузки сценариев потребуется 10,561 с (сообщается с помощью префикса timeк . /opt/local/etc/bash_completionстроке в моем .bash_profileфайле.

После закомментирования PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&строки моего /usr/local/etc/bash_completionсценария (оставление have=yesстроки, открытие нового терминала занимает всего 0,258 с. Это время можно сократить, удалив ненужные сценарии завершения (символические ссылки) из /usr/local/etc/bash_completion.dкаталога.

Я не знаю, почему звонок typeтак долго. Я расследую это дальше.

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

На данный момент я доволен компромиссом, но я буду продолжать исследовать typeпроблему, когда у меня будет время. Я обновлю свой ответ, если найду лучшее решение.

godbyk
источник
Для меня комментирование этой строки сокращает время 50 мс, с 230 мс до 180 мс. Конечно, мне никогда не было так плохо с самого начала. Ed
Эдвард Андерсон
Это только сбрило около 60 мс, так что я не оставил обходной путь. У меня не десять секунд ожидания, а около двух секунд, что немного утомительно.
danemacmillan
7

Для тех , кто приходит к выводу , что время запуска для новых снарядов на MacOS является слишком медленным для них, этого решение .

Я только что обнаружил, что на самом деле есть два пакета, которые можно установить через brew. Я устанавливал bash-completionпакет в течение многих лет, и никогда не удосужился подвергнуть его сомнению, хотя в то время я переходил с Bash 3 на 4, а теперь и на 5. Однако время от времени я возвращался к проблеме часто спотыкается об этом обсуждении StackOverflow.

Там еще один пакет, bash-completion@2!

Какая разница? bash-completionдля Bash версии 3.2. bash-completion@2для Bash версии 4.1+ и 5.

При удалении bash-completionи установке старого пакета bash-completion@2время запуска моей оболочки сократилось с 605 до 244 мс. Это огромное улучшение скорости.

Я подозреваю, что многие из нас совершают ту же ошибку, так как brew infoстатистика показывает, что у первого есть тонны установок, а у последнего так мало:

введите описание изображения здесь

Следует отметить, что в текущем выбранном ответе упоминается закомментирование некоторых строк, что обеспечивает лишь незначительное улучшение времени запуска (если используется старый bash-completionпакет, который, вероятно, есть у многих), но никак не влияет на новый bash-completion@2пакет: этот новый пакет быстро, несмотря ни на что. Это означает, что никаких взломов не требуется.

TL; DR:

brew uninstall bash-completion && brew install bash-completion@2

Не забудьте обновить исходный путь до файла завершения в вашем .bashrcили .bash_profileфайле.

Источники:


Поскольку тема несколько связана, я часто использую rcloneутилиту, поэтому она установлена. Он также имеет самый большой файл завершения, который я когда-либо видел . Удаление этого сокращает время запуска моей оболочки до ~ 120 мс, что очень быстро.


Редактировать:

Для тех, кому нужны технические подробности, объясняющие эту проблему, я подробно писал об этом на форумах Homebrew . Подводя итог, bash-completion@2можно сказать , что причина, по которой это происходит намного быстрее, заключается в том, что он был написан так, чтобы больше не загружать все файлы завершения; вместо этого он загружает файл завершения по требованию, или, как описывает его автор, загружает их без лишних усилий.

danemacmillan
источник
Я думаю, что версия по умолчанию Bash на macOS все еще v3.2 - я не думаю, что она поставляется с Bash v4.2. У вас есть ссылка, где говорится, что macOS поставляется с Bash v4.2 +?
nwinkler
1
@nwinkler Вы были бы правы. Я озадачен, почему я упомянул это, потому что MacOS все еще поставляется с version 3.2.57(1)-release (x86_64-apple-darwin18). Спасибо что подметил это; Я удалил строку из своего поста.
danemacmillan
1
Удивительно, я знаю ... Спасибо за обновление вашего ответа!
nwinkler
3

С мыслью о том, что ответ Godbyk дал мне, я обнаружил, что моя переменная PATH имеет несколько каталогов, которые не имеют никаких двоичных файлов или не существуют, удаление их значительно ускорило его. Другими словами, это ПУТЬ, которую я имел в моем bashrc:

PATH="$GOPATH/bin:/some/directory/not/existing:/some/empty/directory:/some/directory/without/binaries:$PATH"

И тогда я изменил это на:

PATH="$GOPATH/bin:$PATH"

Это было потому, что haveфункция в этом завершении bash искала каждую команду, и у меня было слишком много бесполезных каталогов, которые нужно было посетить для каждого из этих двоичных файлов, удаление их ускорило их.

Фарид Нури Нешат
источник
Мне также удалось изменить время загрузки с примерно 5 секунд до менее чем 1 секунды, удалив пути, которые не существуют, из моей переменной среды PATH.
Juriejan
0

Я была такая же проблема. Несколько простых уловок отладки привели меня к основной причине.

Сначала включите, DEBUG modeчтобы увидеть, что происходит:

export BASH_COMPLETION_DEBUG=true

Это позволяет выполнять подробную печать на консоли, поэтому вы можете увидеть последнюю команду. Теперь вы можете выполнить скрипт в фоновом режиме, и вы увидите, что происходит

. /opt/local/etc/bash_completion &

Не берите из того PID, что вы можете отследить с помощью psили pstree:

pstree -p <the PID>:

| |     \-+= 82095 mfellows -bash
| |       \-+- 82103 mfellows -bash
| |         |-+- 82104 mfellows cargo --list
| |         | \--- 82106 mfellows rustc -vV --cap-lints allow

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

Временное удаление /opt/boxen/homebrew/etc/bash_completion.d/cargoразрешило мои симптомы.

Мэтью Феллоуз
источник
-1

Если вы используете MacPorts> = 2.1.2 и Mountain Lion, значит, вы bash_profileошибаетесь. Следуйте инструкциям на Как заставить git-creation.bash работать на Mac OS X? , Я предполагаю, что это может ускорить автозаполнение.

Другим решением будет попытаться установить автозаполнение через Fink или Homebrew. Если это не сработает, вы можете попробовать другую оболочку. Я обнаружил, что рыбная раковина является выдающейся, когда дело доходит до автозаполнения (из коробки). Хотя версия 2 все еще находится в бета-версии, я очень рекомендую ее.

awek
источник
-1

Я догадываюсь, что твой удар слишком стар. Я работаю на складе, который идет с Mountain Lion, и вот что я вижу:

$ port info bash-completion
bash-completion @2.0, Revision 1 (sysutils)

Description:          Programmable completion library for bash. This port
                      **requires bash >=4.1** and is meant to be used together with
                      the bash port.
Homepage:             http://bash-completion.alioth.debian.org/

Runtime Dependencies: bash
Conflicts with:       bash-completion-devel
Platforms:            darwin
License:              GPL-2+
Maintainers:          raimue@macports.org

$ bash --version
GNU bash, version **3.2.48(1)-release (x86_64-apple-darwin12)**
Copyright (C) 2007 Free Software Foundation, Inc.
числовая иллюстрация
источник
Я не вижу, чтобы иметь эту команду порта. :( Как узнать, какое программное обеспечение для завершения git tab работает на моем Mac.
Дин Хиллер
@DeanHiller Этот ответ относится к менеджеру пакетов Macports, который предоставляет команду порта. Приложение завершения bash в Macports будет более новым, чем приложение, поставляемое с OS X.
Matt S