Dlaczego w systemie OS X ładowanie bash jest tak wolne?

16

Nie rozumiem, dlaczego ukończenie bash jest tak wolno ładowane na moim MacBooku Pro.

Wykonałem następujące czynności w moim ~/.bash_profile:

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

czas wykonania dla bash_completion zwykle wynosi> 2 sekundy.

Uważam to za bardzo denerwujące, gdy pracuję nad terminalem, który wymaga ode mnie ciągłego otwierania nowych kart.

Czy jest jakiś sposób, że mogę to buforować?

(Uwaga: Używam iTerm2 i jest to równie powolne na oryginalnym terminalu w Macu).

zniknął
źródło
To nie powinno się dziać. Czy mam rację, że używasz kompilacji MacPorta?
slhck
Jak wygląda ten ładowany plik?
Daniel Beck
@slhck: Tak, rzeczywiście używam zakończenia bash'u Macporta
zniknął
@Daniel: Wszystko jest w porządku, z wyjątkiem tego. Profilowałem prawie każdą linię.
zniknął
5
Mam tę samą powolność i używam Homebrew.
Brice

Odpowiedzi:

10

Wersja skrócona: Usunięcie pojedynczej linii ze /usr/local/etc/bash_completionskrócenia czasu otwierania nowej karty z dziesięciu sekund do ćwierć sekundy. Czytaj dalej, aby poznać szczegóły.

Korzystam z bash-uzupełniania z homebrew i napotkałem ten sam problem. Załadowanie skryptów kończących bash trwało ponad dziesięć sekund za każdym razem, gdy otwierałem terminal.

Przez większość czasu wydaje się, że zajmuje go pojedynczy wiersz have()funkcji: wywołanie w typecelu ustalenia, czy program wiersza poleceń jest zainstalowany.

Przy domyślnej have()funkcji i wszystkich dostarczonych skryptach kończących bash, załadowanie skryptów zajmie 10.561s (zgłaszane przez prefiks timedo . /opt/local/etc/bash_completionlinii w moim .bash_profilepliku).

Po skomentowaniu PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&wiersza mojego /usr/local/etc/bash_completionskryptu (opuszczenie have=yeswiersza, otwarcie nowego terminala zajmuje tylko 0,258 s. Czas ten można dodatkowo skrócić, usuwając niepotrzebne skrypty ukończenia (dowiązania symboliczne) z /usr/local/etc/bash_completion.dkatalogu.

Nie wiem, dlaczego wezwanie do typetak długo trwa. Sprawdzam to później.

Jednym potencjalnym minusem tego podejścia jest to, że spowoduje załadowanie funkcji uzupełniania bashu do pamięci, nawet jeśli nie będziesz z nich korzystać. Te have()kontrole funkcyjne, aby zobaczyć, czy jest zainstalowany polecenia lub aplikacji. Jeśli tak nie jest, skrypt zakończenia generalnie decyduje się nie zawracać sobie głowy ładowaniem, ponieważ nie będzie to przydatne.

W tej chwili jestem zadowolony z kompromisu, ale będę nadal badał typeproblem, gdy będę miał czas. Zaktualizuję swoją odpowiedź, jeśli znajdę lepsze rozwiązanie.

cholerny
źródło
Dla mnie komentowanie tej linii skraca czas 50 ms, z 230 ms do 180 ms. Oczywiście nigdy nie miałem tak źle. 👍
Edward Anderson
Ogoliłem to tylko około 60 ms, więc nie zachowałem obejścia. Nie mam dziesięciu sekund oczekiwania, ale około 2 sekund, co jest nieco irytujące.
danemacmillan
7

Dla każdego, kto dojdzie do wniosku, że czasy uruchamiania nowych powłok w systemie MacOS są dla nich zbyt wolne, jest to rozwiązanie .

Właśnie odkryłem, że w rzeczywistości istnieją dwa pakiety, które można zainstalować brew. Instaluję bash-completionpakiet od lat i nigdy nie zadałem sobie trudu, aby go zakwestionować, mimo że w tym czasie przeszedłem z Bash 3, 4, teraz 5. Jednak od czasu do czasu wracam do problemu , często napotykam na tę dyskusję StackOverflow.

Jest kolejna paczka bash-completion@2!

Co za różnica? bash-completiondotyczy wersji Bash 3.2. bash-completion@2dotyczy wersji Bash 4.1+ i 5.

Po usunięciu starego bash-completionpakietu i zainstalowaniu bash-completion@2mój czas uruchamiania powłoki spadł z 605 ms do 244 ms. To ogromna poprawa prędkości.

Podejrzewam, że wielu z nas popełnia ten sam błąd, ponieważ brew infostatystyki pokazują, że ten pierwszy ma mnóstwo instalacji, podczas gdy drugi ma tak mało:

wprowadź opis zdjęcia tutaj

Należy zauważyć, że obecnie wybrana odpowiedź wspomina o komentowaniu niektórych wierszy, co zapewnia jedynie niewielką poprawę czasów uruchamiania (jeśli używa się starego bash-completionpakietu, którym prawdopodobnie wielu jest), ale nie ma żadnego wpływu na nowy bash-completion@2pakiet: ten nowy pakiet jest szybki bez względu na wszystko. Oznacza to, że nie wymaga hackowania.

TL; DR:

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

Pamiętaj, aby zaktualizować ścieżkę źródłową do pliku zakończenia w pliku .bashrclub .bash_profilepliku.

Źródła:


Jako temat nieco powiązany, rcloneczęsto używam tego narzędzia, więc jest zainstalowane. Zdarza się również, że ma największy plik ukończenia, jaki kiedykolwiek widziałem . Usunięcie go skraca czas uruchamiania mojej powłoki do ~ 120 ms, co jest bardzo szybkie.


Edytować:

Dla każdego, kto chce poznać szczegóły techniczne wyjaśniające ten problem, pisałem o tym obszernie na forach Homebrew . Podsumowując, powodem, który bash-completion@2jest o wiele szybszy, jest to, że został napisany tak, że nie chętnie ładuje już wszystkich plików ukończenia; zamiast tego ładuje plik ukończenia na żądanie lub, jak opisuje go autor, ładuje je w nieskory sposób.

danemacmillan
źródło
Myślę, że domyślna wersja Bash w systemie macOS to wciąż wersja 3.2 - nie sądzę, że jest dostarczana z wersją Bash wer. 4.2. Czy masz odniesienie, w którym napisano, że macOS jest dostarczany z Bash v4.2 +?
nwinkler
1
@nwinkler Miałbyś rację. Zastanawiam się, dlaczego o tym wspomniałem, ponieważ MacOS wciąż jest w zestawie version 3.2.57(1)-release (x86_64-apple-darwin18). Dzięki za zwrócenie na to uwagi; Usunąłem wiersz z mojego postu.
danemacmillan
1
Zaskakujące, wiem ... Dzięki za aktualizację twojej odpowiedzi!
nwinkler
3

Dzięki pomysłowi, który dał mi odpowiedź godbyk, odkryłem, że moja zmienna PATH miała kilka katalogów, które nie miały żadnych plików binarnych lub nie istniały, co znacznie je przyspieszyło. Innymi słowy, jest to ŚCIEŻKA, którą miałem w moim bashrc:

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

A potem zmieniłem to na:

PATH="$GOPATH/bin:$PATH"

Stało się tak, ponieważ havefunkcja w tym zakończeniu bashu szukała każdego polecenia, a ja miałem zbyt wiele bezużytecznych katalogów, które miały być odwiedzane dla każdego z tych plików binarnych, co spowodowało ich przyspieszenie.

Farid Nouri Neshat
źródło
Udało mi się również zmienić czas ładowania z około 5 sekund na mniej niż 1 sekundę, usuwając ścieżki, które nie istnieją z mojej zmiennej środowiskowej PATH.
juriejan
0

Miałem ten sam problem. Kilka prostych sztuczek debugowania doprowadziło mnie do głównej przyczyny.

Najpierw włącz, DEBUG modeaby zobaczyć, co się dzieje:

export BASH_COMPLETION_DEBUG=true

Umożliwia to pełne drukowanie na konsoli, dzięki czemu można zobaczyć ostatnie polecenie. Możesz teraz wykonać skrypt w tle, a zobaczysz, co się dzieje

. /opt/local/etc/bash_completion &

Nie bierz tego PID, co możesz następnie śledzić za pomocą pslub pstree:

pstree -p <the PID>:

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

Jak widać, uruchomiono kilka poleceń związanych z rdzą, które trwały wieki.

Tymczasowe usunięcie /opt/boxen/homebrew/etc/bash_completion.d/cargorozwiązało moje objawy.

Matthew Fellows
źródło
-1

Jeśli korzystasz z MacPorts> = 2.1.2 i Mountain Lion, to wygląda na to, że się bash_profilemylisz. Postępuj zgodnie z instrukcjami na stronie Jak uzyskać git-uzupełnianie.bash do pracy w systemie Mac OS X? . Zakładam, że może to przyspieszyć automatyczne uzupełnianie.

Innym rozwiązaniem może być próba zainstalowania autouzupełniania za pośrednictwem Fink lub Homebrew. Jeśli to nie zadziała, możesz wypróbować inną powłokę. Przekonałem się, że skorupa ryb jest wyjątkowa, jeśli chodzi o automatyczne uzupełnianie (po wyjęciu z pudełka). Chociaż wersja 2 jest wciąż w fazie beta, bardzo ją polecam.

awek
źródło
-1

Domyślam się, że twoja bata jest za stara. Używam bashu giełdowego, który przyszedł z Mountain Lion i oto, co widzę:

$ 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.
ilustracja numeryczna
źródło
Nie widzę tego polecenia portu. :( Jak dowiedzieć się, które oprogramowanie do uzupełniania kart git działa na moim komputerze Mac
Dean Hiller
@DeanHiller Ta odpowiedź dotyczy menedżera pakietów Macports, który udostępnia polecenie port. Aplikacja do ukończenia bashu w Macports będzie nowsza niż ta dostarczana z OS X.
Matt S