Por que a conclusão do bash está sendo carregada tão lentamente no OS X?


16

Não entendo por que a conclusão do bash é carregada tão lentamente no meu MacBook Pro.

Eu fiz o seguinte no meu ~/.bash_profile:

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

o tempo de execução para bash_completion normalmente é> 2 segundos.

Eu acho isso muito chato quando estou trabalhando no terminal, o que exige que eu abra constantemente novas abas.

Existe uma maneira de armazenar isso em cache ou algo assim?

(Observe que estou usando o iTerm2 e isso também é lento no terminal original do Mac).


Isso não deveria estar acontecendo. Estou correto de usar a conclusão do basport do MacPort?
slhck

Como é esse arquivo que você carrega?
Daniel Beck

@slhck: Sim, eu realmente estou usando conclusão a festança da MacPort
disappearedng

@ Daniel: Está tudo bem, exceto por isso. Eu perfilei quase todas as linhas.
disappearedng

5
Sinto a mesma lentidão e estou usando o Homebrew.
Brice

Respostas:


10

Versão curta: a remoção de uma única linha /usr/local/etc/bash_completionreduziu o tempo para abrir uma nova guia de dez segundos para um quarto de segundo. Continue lendo para obter detalhes.

Estou usando o bash-complete do homebrew e encontrou o mesmo problema. Demorava mais de dez segundos para carregar os scripts de conclusão do bash cada vez que eu abria um terminal.

Na maioria das vezes, parece que é ocupado por uma única linha na have()função: uma chamada typepara determinar se um programa de linha de comando está instalado.

Com a have()função padrão e todos os scripts de conclusão do bash fornecidos, seriam necessários 10.561s para carregar os scripts (relatados prefixando timea . /opt/local/etc/bash_completionlinha no meu .bash_profilearquivo.

Depois de comentar a PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&linha do meu /usr/local/etc/bash_completionscript (sair da have=yeslinha, a abertura de um novo terminal leva apenas 0,258s. Esse tempo pode ser reduzido ainda mais com a remoção de scripts de conclusão desnecessários (links simbólicos) do /usr/local/etc/bash_completion.ddiretório.

Não sei por que a ligação typeestá demorando tanto. Estou investigando isso a seguir.

Uma desvantagem potencial dessa abordagem é que ela fará com que as funções de conclusão do bash sejam carregadas na memória, mesmo que você não as utilize. A have()função verifica se um comando ou aplicativo está instalado. Caso contrário, o script de conclusão geralmente decide não se incomodar em carregar a si próprio, porque será inútil.

No momento, estou feliz com a troca, mas continuarei a explorar o typeproblema à medida que tiver tempo. Atualizarei minha resposta se encontrar uma solução melhor.


Para mim, comentar esta linha reduz o tempo de 50ms, de 230ms para 180ms. É claro que nunca tive tanto mal em primeiro lugar.
Edward

Isso só diminuiu cerca de 60ms, por isso não mantive a solução alternativa. Não tenho tempos de espera de dez segundos, mas cerca de 2s, o que é levemente cansativo.
Danemacmillan

7

Para quem chega à conclusão de que os tempos de inicialização de novos shells no MacOS são muito lentos para eles, esta é a solução .

Acabei de descobrir que existem de fato dois pacotes que podem ser instalados via brew. Estou instalando o bash-completionpacote há anos e nunca me incomodei em questioná-lo, embora nesse período eu tenha passado do Bash 3 para o 4 e agora para o 5. Agora, de vez em quando, eu revisitava o problema. , frequentemente tropeçando nessa discussão do StackOverflow.

Há outro pacote bash-completion@2!

Qual é a diferença? bash-completioné para o Bash versão 3.2. bash-completion@2é para o Bash versão 4.1 ou superior e 5.

Ao remover o bash-completionpacote antigo e instalar bash-completion@2, meus tempos de inicialização do shell caíram de 605ms para 244ms. Essa é uma enorme melhoria de velocidade.

Eu suspeito que muitos de nós estão cometendo esse mesmo erro, pois as brew infoestatísticas mostram que o primeiro tem toneladas de instalações, enquanto o segundo tem tão poucos:

insira a descrição da imagem aqui

Deve-se observar que a resposta escolhida atual menciona o comentário de algumas linhas, o que fornece apenas uma ligeira melhora nos tempos de inicialização (se você estiver usando o bash-completionpacote antigo , o que provavelmente é o caso), mas não tem nenhum impacto no novo bash-completion@2pacote: este novo pacote é rápido, não importa o quê. Isso significa que não são necessários hacks.

TL; DR:

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

Lembre-se de atualizar o caminho de origem para o arquivo de conclusão no seu arquivo .bashrcou .bash_profile.

Fontes:


Como um tópico relacionado, eu uso muito o rcloneutilitário, portanto ele está instalado. Também tem o maior arquivo de conclusão que eu já vi . Removê-lo reduz o tempo de inicialização do meu shell para ~ 120ms, o que é muito rápido.


Editar:

Para quem deseja os detalhes técnicos que explicam esse problema, escrevi sobre isso nos fóruns da Homebrew . Para resumir, a razão que bash-completion@2é muito mais rápido é porque ele foi escrito de modo que já não ansiosamente carrega todos os arquivos de conclusão; em vez disso, carrega um arquivo de conclusão sob demanda ou, como o autor descreve, carrega- os de maneira não-ansiosa .


Acho que a versão padrão do Bash no macOS ainda é a v3.2 - não acho que ela seja fornecida com o Bash v4.2. Você tem uma referência em que diz que o macOS é fornecido com o Bash v4.2 +?
Nwinkler #

1
@nwinkler Você estaria correto. Estou confuso por que mencionei isso, porque o MacOS ainda acompanha version 3.2.57(1)-release (x86_64-apple-darwin18). Obrigado por apontar isso; Eu removi a linha da minha postagem.
danemacmillan

1
Desconcertante, eu sei ... Obrigado por atualizar sua resposta!
Nwinkler # 10/19

3

Com a idéia que a resposta godbyk me deu, eu descobri que minha variável PATH tinha alguns diretórios que não tinham binários ou que não existiam, removendo-os acelerando significativamente. Em outras palavras, este é o PATH que eu tinha no meu bashrc:

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

E então eu mudei para:

PATH="$GOPATH/bin:$PATH"

Isso porque a havefunção nessa conclusão do bash procurava cada comando e eu tinha muitos diretórios inúteis que seriam visitados por cada um desses binários, removendo-os de forma acelerada.


Também consegui alterar o tempo de carregamento de cerca de 5 segundos para menos de 1 segundo removendo caminhos que não existem da minha variável de ambiente PATH.
precisa saber é

0

Eu tive o mesmo problema. Alguns truques simples de depuração me levaram à causa raiz.

Primeiro, ative DEBUG modepara que você possa ver o que está acontecendo:

export BASH_COMPLETION_DEBUG=true

Isso permite a impressão detalhada no console, para que você possa ver o último comando. Agora você pode executar o script em segundo plano e verá o que está acontecendo

. /opt/local/etc/bash_completion &

Não use o PIDque você pode rastrear com psou pstree:

pstree -p <the PID>:

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

Como você pode ver, iniciou alguns comandos relacionados à ferrugem, que estavam demorando muito.

A remoção temporária /opt/boxen/homebrew/etc/bash_completion.d/cargoresolveu meus sintomas.


-1

Se você estiver executando o MacPorts> = 2.1.2 e o Mountain Lion, parece que bash_profileestá errado. Siga as instruções em Como obter o git-complete.bash para trabalhar no Mac OS X? . Suponho que isso poderia acelerar a conclusão automática.

Outra solução seria tentar instalar o preenchimento automático via Fink ou Homebrew. Se isso não funcionar, você pode tentar outro shell completamente. Descobri que a casca do peixe é excelente quando se trata de preenchimento automático (pronto para uso). Embora a versão 2 ainda esteja na versão beta, eu a recomendo.


-1

Vou adivinhar que sua festa é muito antiga. Estou executando o estoque bash que veio com o Mountain Lion e aqui está o que vejo:

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

Não vejo esse comando de porta. :( Como faço para descobrir qual software a conclusão de tabulação git está em execução no meu mac.
Dean Hiller

@DeanHiller Esta resposta está se referindo ao gerenciador de pacotes Macports, que fornece o comando port. Aplicativo conclusão Bash Macports será mais recente que a versão disponível com o OS X.
Matt S
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.