Чому завершення 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).


Так не повинно відбуватися. Я правда, ви використовуєте башти MacPort?
slhck

Як виглядає той файл, який ви завантажуєте?
Даніель Бек

@slhck: Так, я справді використовую завершення макпорту
зник

@Daniel: Все добре, окрім цього. Я профілював майже кожен рядок.
зник

5
Я відчуваю таку ж повільність, і я використовую Homebrew.
Бріс

Відповіді:


10

Коротка версія: Видалення одного рядка зі /usr/local/etc/bash_completionскорочення часу на відкриття нової вкладки з десяти секунд до чверті секунди. Детальніше читайте далі.

Я використовую bash-завершення від домашньої мови та зіткнувся з тією ж проблемою. На завантаження скриптів для завершення башти було потрібно більше десяти секунд щоразу, коли я відкривав термінал.

Більшу частину цього часу, здається, займає один рядок у have()функції: виклик, typeщоб визначити, чи встановлена ​​програма командного рядка.

Якщо have()функція за замовчуванням і всі передбачені сценарії завершення bash на місці, потрібно буде 10.561s завантажити сценарії (повідомляється шляхом префіксації 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проблему, коли отримаю час. Я оновлю свою відповідь, якщо знайду краще рішення.


Для мене, коментуючи цей рядок, скорочується час на 50 мс, з 230 мс до 180 мс. Звичайно, мені ніколи не було так погано в першу чергу. 👍
Едвард Андерсон

Це лише поголилося близько 60 мс, тому я не дотримався рішення. У мене немає десяти секунд часу очікування, але приблизно 2 секунди, що м'яко неприємно.
danemacmillan

7

Для тих , хто приходить до висновку , що час запуску для нових снарядів на MacOS є занадто повільним для них, цього рішення .

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

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

Яка різниця? bash-completionпризначений для версії 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відбувається набагато швидше, полягає в тому, що вона була написана так, що вона більше не охоче завантажує всі файли завершення; натомість він завантажує файл на завершення на вимогу, або, як автор описує його, він завантажує їх нетерплячим чином.


Я думаю, що за замовчуванням версія 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 мала кілька каталогів, які не мали жодних двійкових файлів або не існували, видаляючи їх, значно збільшували їх. Іншими словами, це ПАТ, який я мав у своєму башерку:

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-fill.bash працювати на Mac OS X? . Я припускаю, що це може пришвидшити автоматичне завершення.

Іншим рішенням буде спробувати встановити автозаповнення через Fink або Homebrew. Якщо це не працює, ви можете спробувати ще одну оболонку. Я виявив, що шкаралупа Fish є видатною, коли мова йде про автоматичне завершення (поза коробкою). Хоча версія 2 все ще знаходиться в бета-версії, я б дуже рекомендував її.


-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 працює на моєму комп'ютері.
Дін Хіллер,

@DeanHiller Ця відповідь стосується менеджера пакунків Macports, який надає команду порта. Додаток для завершення башти Macports буде новішим, ніж той, що надається в OS X.
Метт S,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.