A conclusão do Bash faz com que o bash comece lentamente

15

Iniciar uma festança no meu sistema ubuntu leva cerca de 2 segundos. Se eu remover o carregamento / etc / bash_completition no .bashrc, ele iniciará sem demora. Claro que não quero desistir da conclusão e não acho que carregar esse arquivo seja motivo legítimo para um atraso de 2 segundos.

Alguma idéia de como posso descobrir qual é o problema ou como posso acelerar as coisas.

user75250
fonte
é isso / bin / bash? - try / bin / dash pode ser um pouco mais rápido.
Sirex
3
É por isso que eu desinstalei o bash-complete
Vi.

Respostas:

8

Atualização em 2013: a maior parte da conclusão do bash foi reescrita para carregar automaticamente conclusões apenas quando necessário. O script principal é muito mais ligeiro agora.


Às vezes, o script de conclusão pode ser enorme nos padrões de script de shell. Nos servidores em que tenho acesso, são quase 1700 linhas (57 KB) e esse é apenas o script principal . Em /etc/bash_completion.dhá ~ 200 scripts adicionais para vários outros comandos ( openssl, mutt, mount...) totalizando 25537 linhas ou 1.2 MB. Cada script, quando originado, verifica se um comando está realmente disponível antes de definir os manipuladores de conclusão; ~ 330 vezes neste caso, cada uma das quais envolve a verificação $PATHde um arquivo executável com um determinado nome. (Embora eu esperasse /usr/binser armazenado em cache na memória ...)

É certo que mesmo isso leva apenas meio segundo para carregar, e não dois segundos completos. Mas pode ser pelo menos parte do problema. Execute du -hs /etc/bash_completion*ou wc -l /etc/bash_completion{,.d/*} | grep totalse você deseja verificar.


Você pode tentar obter o script manualmente, no modo "rastreio":

set -x
. /etc/bash_completion

Você verá cada linha conforme é executada. Se houver um comando específico que leva muito tempo, você deve notá-lo.

( set +xdesativa o modo de rastreamento.)

user1686
fonte
Característica fluência mesmo no modo de texto simplista? É mais provável do que você pensa.
Vi.
@Vi: Depois de ver zsh compilar seus scripts de inicialização para bytecode ...
user1686
11
Obrigado. Isso foi realmente fácil. Infelizmente, todos os comandos não eram perceptíveis diferentes. Portanto, parece que é realmente a enorme quantidade que está causando o problema.
user75250
12

Eu encontrei uma solução um pouco hackiana que parece funcionar bastante.

Solução

Na parte inferior do ~/.bashrcadd:

trap 'source / etc / bash_completion; interceptar USR1 'USR1
{sono 0,1; kill embutido -USR1 $$; } e renegado

Explicação

trap 'source /etc/bash_completion ; trap USR1' USR1

Configure um manipulador para ser executado quando o shell receber o sinal SIGUSR1; o manipulador carregará as conclusões e, portanto, será desativado.

{ sleep 0.1 ; builtin kill -USR1 $$ ; } & disown

Aguarde um pouco de forma assíncrona e depois envie o sinal para o shell atual. disowné necessário para suprimir o bashfeedback do controle do processo. sleepé necessário para trabalhar de forma assíncrona.

Problemas

Por alguma razão, o primeiro comando emitido para esse shell não será registrado no histórico.

cYrus
fonte
11
Isso não parece dar um impulso na inicialização - time bash -lc truerelata ~ 0,12s com ou sem isso, apesar de time source /etc/bash_completionrelatar números mais altos como 0,26s. Isso foi efetivamente corrigido ?
precisa saber é
Eu não sei se time bash -lc truefunciona corretamente aqui, pois truetermina antes, ~0.1spara que não obtenha nada. De qualquer forma, time source /etc/bash_completionrelata ~ 0,17s aqui e é sobre o tempo que eu preciso esperar pela PS1aparição.
CYrus 13/04
2
Engenhoso! Na explicação, os comandos trap perdem a USR1no final.
Fish Monitor
Com o SIGUSR, o manipulador de sinal não é chamado até que eu pressione enter no prompt do shell. Há uma pausa nesse momento enquanto ele é executado. Mudei para SIGQUIT e parece funcionar bem.
Jon Nalley
5

Você deve usar a versão mais recente (2.0) do bash_completion. Se você estiver usando o Debian, ele está no wheezy, mas não depende de nenhum outro pacote wheezy, portanto você pode instalá-lo rapidamente e sem problemas.

A versão mais recente carrega a conclusão dinamicamente em tempo real, por isso dividiu o tempo de carregamento rápido para mim em pelo menos 10x.

xryl669
fonte
1

Você pode usar um espaço reservado enquanto as conclusões estão sendo carregadas; deve ser o suficiente para enganar seus olhos. Obviamente, isso funcionará apenas se o tempo necessário source /etc/bash_completionfor menor que o tempo necessário para você digitar e emitir o primeiro comando do shell, caso contrário também será atrasado.

A idéia é ecoar uma farsa PS1, obter as conclusões e finalmente eliminar o terminal.

Suponha que você PS1seja \u@\h:\w\$, eles podem escrever algo como:

echo -ne "$USER@$HOSTNAME:${PWD/$HOME/\~}\$ "
source /etc/bash_completion
echo -ne '\e[2J\e[H'

Onde:

  • 2J apaga o terminal;
  • H mova o cursor para o canto superior direito.

Nota: convém verificar se o usuário é root e usa em #vez de $obter consistência:

echo -ne "...$([ $UID = 0 ] && echo '#' || echo '$') "

Nota: A remoção \e[2Jevita a tremulação, mas deixa caracteres indesejados se o espaço reservado for maior que o prompt real.

cYrus
fonte