Perché il completamento di bash viene caricato così lentamente su OS X?


16

Non capisco perché il completamento della bash sia caricato così lentamente sul mio MacBook Pro.

Ho fatto quanto segue nel mio ~/.bash_profile:

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

il tempo di esecuzione per bash_completion è in genere> 2 secondi.

Lo trovo davvero fastidioso quando lavoro sul terminale che mi richiede di aprire costantemente nuove schede.

C'è un modo per memorizzare nella cache questo o qualcosa del genere?

(Nota che sto usando iTerm2 e questo è altrettanto lento sul terminale originale anche in Mac).


Non dovrebbe succedere. Ho ragione a usare il completamento bash di MacPort?
slhck,

Che aspetto ha quel file che carichi?
Daniel Beck

@slhck: Sì, sto davvero usando il completamento bash di macport
scomparso il

@Daniel: va tutto bene tranne questo. Ho profilato quasi ogni riga.
scomparso il

5
Provo la stessa lentezza e sto usando Homebrew.
Brice,

Risposte:


10

Versione breve: la rimozione di una singola riga /usr/local/etc/bash_completionriduce il tempo di apertura di una nuova scheda da dieci secondi a un quarto di secondo. Continua a leggere per i dettagli.

Sto usando bash-completamento da homebrew e ho riscontrato lo stesso problema. Ci sono voluti più di dieci secondi per caricare gli script di completamento bash ogni volta che ho aperto un terminale.

Il più delle volte, sembra essere occupato da una singola linea nella have()funzione: una chiamata typeper determinare se è installato un programma da riga di comando.

Con la have()funzione predefinita e tutti gli script di completamento bash forniti attivi, occorrerebbero 10.561 secondi per caricare gli script (segnalati prefissando timela . /opt/local/etc/bash_completionriga nel mio .bash_profilefile.

Dopo aver commentato la PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&riga del mio /usr/local/etc/bash_completionscript (lasciando la have=yesriga, l'apertura di un nuovo terminale richiede solo 0,258 secondi. Questa volta potrebbe essere ulteriormente ridotta rimuovendo gli script di completamento (link simbolici) non necessari dalla /usr/local/etc/bash_completion.ddirectory.

Non so perché la chiamata a typesta impiegando così tanto tempo. Lo indagherò dopo.

Un potenziale svantaggio di questo approccio è che causerà il caricamento in memoria di funzioni di completamento bash anche se non sono utili. La have()funzione controlla se è installato un comando o un'applicazione. In caso contrario, lo script di completamento generalmente decide di non preoccuparsi di caricare se stesso perché non sarà di alcuna utilità.

Al momento, sono contento del compromesso, ma continuerò a esplorare il typeproblema man mano che avrò tempo. Aggiornerò la mia risposta se trovo una soluzione migliore.


Per me, commentare questa riga riduce i tempi di 50ms, da 230ms a 180ms. Ovviamente non l'ho mai avuto così male in primo luogo. 👍
Edward Anderson,

Questo si è rasato solo circa 60 ms, quindi non ho mantenuto la soluzione alternativa. Non ho dieci secondi di attesa, ma circa 2 secondi, il che è leggermente fastidioso.
danemacmillan,

7

Per chiunque giunga alla conclusione che i tempi di avvio per le nuove shell su MacOS sono troppo lenti per loro, questa è la soluzione .

Ho appena scoperto che ci sono in realtà due pacchetti che possono essere installati tramite brew. Ho installato il bash-completionpacchetto per anni e non mi sono mai preso la briga di metterlo in discussione, anche se in quel momento sono passato da Bash 3, a 4, ad ora 5. Di tanto in tanto, però, rivisitavo il problema , spesso inciampando in questa discussione StackOverflow.

C'è un altro pacchetto bash-completion@2,!

Qual è la differenza? bash-completionè per Bash versione 3.2. bash-completion@2è per Bash versione 4.1+ e 5.

Rimuovendo il vecchio bash-completionpacchetto e installandolo bash-completion@2, i tempi di avvio della mia shell sono passati da 605ms a 244ms. Questo è un enorme miglioramento della velocità.

Sospetto che molti di noi stiano commettendo questo stesso errore, poiché le brew infostatistiche mostrano che il primo ha tonnellate di installazioni, mentre il secondo ha così pochi:

inserisci qui la descrizione dell'immagine

Va notato che l' attuale risposta scelta menziona commentando alcune righe, il che fornisce solo un leggero miglioramento dei tempi di avvio (se si utilizza il vecchio bash-completionpacchetto, che molti probabilmente lo sono), ma non ha alcun impatto sul nuovo bash-completion@2pacchetto: questo nuovo pacchetto è veloce, qualunque cosa accada. Ciò significa che non sono necessari hack.

TL; DR:

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

Ricorda di aggiornare il percorso di origine al file di completamento nel tuo .bashrco .bash_profilefile.

fonti:


Come argomento in qualche modo correlato, uso molto l' rcloneutilità, quindi è installata. Capita anche di avere il file di completamento più grande che abbia mai visto . Rimuoverlo riduce i tempi di avvio della mia shell a ~ 120ms, il che è molto veloce.


Modificare:

Per chiunque desideri i dettagli tecnici che spiegano questo problema, ne ho scritto a lungo sui forum di Homebrew . Riassumendo, il motivo che bash-completion@2è molto più veloce è perché è stato scritto in modo che non carichi più avidamente tutti i file di completamento; invece carica un file di completamento su richiesta o, come descritto dall'autore, li carica in modo non desideroso .


Penso che la versione predefinita di Bash su macOS sia ancora v3.2 - Non penso che sia fornita con Bash v4.2. Hai un riferimento in cui si dice che macOS viene fornito con Bash v4.2 +?
nwinkler,

1
@nwinkler Avresti ragione. Sono perplesso sul motivo per cui mi è capitato di menzionarlo, perché MacOS è ancora disponibile version 3.2.57(1)-release (x86_64-apple-darwin18). Grazie per la segnalazione; Ho rimosso la riga dal mio post.
danemacmillan,

1
Sconcertante, lo so ... Grazie per aver aggiornato la tua risposta!
nwinkler

3

Con l'idea che Godbyk mi abbia dato la risposta, ho scoperto che la mia variabile PATH aveva alcune directory che non avevano binari o non esistevano, rimuovendole accelerate significativamente. In altre parole, questo è il PERCORSO che avevo nel mio bashrc:

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

E poi l'ho cambiato in:

PATH="$GOPATH/bin:$PATH"

Questo perché la havefunzione in quel completamento bash, cercava ogni comando, e avevo troppe directory inutili che sarebbero state visitate per ognuno di quei binari, rimuovendoli accelerati.


Sono anche riuscito a modificare il tempo di caricamento da circa 5 secondi a meno di 1 secondo rimuovendo i percorsi che non esistono dalla mia variabile d'ambiente PATH.
Juriejan,

0

Ho avuto lo stesso problema. Alcuni semplici trucchi di debug mi hanno portato alla causa principale.

Innanzitutto, abilita in DEBUG modemodo da poter vedere cosa sta succedendo:

export BASH_COMPLETION_DEBUG=true

Ciò consente la stampa dettagliata sulla console, in modo da poter vedere l'ultimo comando. Ora puoi eseguire lo script in background e vedrai cosa sta succedendo

. /opt/local/etc/bash_completion &

Prendi non del PID, che puoi quindi tracciare con pso pstree:

pstree -p <the PID>:

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

Come puoi vedere, ha avviato alcuni comandi relativi alla ruggine, che richiedevano anni.

La rimozione temporanea ha /opt/boxen/homebrew/etc/bash_completion.d/cargorisolto i miei sintomi.


-1

Se usi MacPorts> = 2.1.2 e Mountain Lion sembra che tu bash_profileabbia torto. Segui le istruzioni su Come far funzionare git-completamento.bash su Mac OS X? . Presumo che potrebbe accelerare il completamento automatico.

Un'altra soluzione sarebbe provare a installare il completamento automatico tramite Fink o Homebrew. Se il problema persiste, puoi provare del tutto un'altra shell. Ho scoperto che Fish shell è eccezionale quando si tratta di auto-completamento (pronto all'uso). Sebbene la versione 2 sia ancora in beta, la consiglio vivamente.


-1

Immagino che il tuo bash sia troppo vecchio. Sto eseguendo Stock Bash fornito con Mountain Lion ed ecco cosa vedo:

$ 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.

Non vedo di avere questo comando di porta. :( Come faccio a sapere quale software di completamento di git tab è in esecuzione sul mio Mac.
Dean Hiller

@DeanHiller Questa risposta si riferisce al gestore di pacchetti Macports, che fornisce il comando port. L'app di completamento bash di Macports sarà più recente di quella fornita con OS X.
Matt S
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.