Il completamento di Bash fa iniziare lentamente la bash


15

L'avvio di una bash sul mio sistema Ubuntu richiede circa 2 secondi. Se rimuovo il caricamento di / etc / bash_completition in .bashrc, questo inizia senza indugio. Ovviamente non voglio rinunciare al completamento e non penso che il caricamento di quel file sia un motivo legittimo per un ritardo di 2 secondi.

Qualche idea su come posso scoprire qual è il problema o come posso accelerare le cose.


è questo / bin / bash? - try / bin / dash potrebbe essere un po 'più veloce.
Sirex,

3
Questo è il motivo per cui ho disinstallato bash-completamento
Vi.

Risposte:


8

Aggiornamento nel 2013: la maggior parte del completamento della bash è stata riscritta per completare i caricamenti automatici solo quando necessario. La sceneggiatura principale ora è molto più leggera.


Lo script di completamento a volte può essere enorme negli standard di script di shell. Su un server a cui ho accesso, sono quasi 1700 righe (57 KB) e questo è solo lo script principale . Nel /etc/bash_completion.dci sono ~ 200 script aggiuntivi per i vari altri comandi ( openssl, mutt, mount...) per un totale di 25537 righe o 1.2 MB. Ogni script, quando fornito, verifica se un comando è effettivamente disponibile prima di definire i gestori di completamento; ~ 330 volte in questo caso, ognuna delle quali comporta la $PATHricerca di un file eseguibile con un determinato nome. (Anche se mi aspetterei /usr/bindi essere memorizzato nella cache in memoria ...)

Certo, anche questo richiede solo mezzo secondo per caricare, non due secondi interi. Ma potrebbe essere almeno una parte del problema. Esegui du -hs /etc/bash_completion*o wc -l /etc/bash_completion{,.d/*} | grep totalse vuoi controllare.


Puoi provare a trovare manualmente lo script, in modalità "trace":

set -x
. /etc/bash_completion

Vedrai ogni riga mentre viene eseguita. Se c'è un comando particolare che richiede molto tempo, dovresti notarlo.

( set +xdisabilita la modalità traccia.)


Strisciamento delle funzionalità anche in modalità testo semplicistica? È più probabile di quanto pensi.
Vi.

@Vi: dopo aver visto zsh compilare i suoi script di avvio in bytecode ...
user1686

1
Grazie. Questo è stato davvero facile. Purtroppo tutti i comandi non erano notevolmente diversi. Quindi sembra proprio la quantità enorme che sta causando il problema.
user75250

12

Ho trovato una soluzione un po 'hacker che sembra funzionare abbastanza bene.

Soluzione

Nella parte inferiore di ~/.bashrcaggiungi:

trap 'source / etc / bash_completion; trap USR1 'USR1
{sonno 0.1; builtin kill -USR1 $$; } e rinnegare

Spiegazione

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

Configurare un gestore da eseguire quando la shell riceve il segnale SIGUSR1; il gestore caricherà i completamenti e quindi si disattiverà da solo.

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

Attendere un po 'in modo asincrono, quindi inviare il segnale alla shell corrente. disownè necessario per sopprimere il bashfeedback sul controllo di processo. sleepè necessario per funzionare in modo asincrono.

I problemi

Per qualche motivo il primo comando impartito a questa shell non verrà registrato nella cronologia.


1
Questo non sembra dare un impulso all'avvio: time bash -lc trueriporta ~ 0,12 secondi con o senza questo, anche se time source /etc/bash_completionriporta numeri più alti come 0,26 secondi. Questo è stato effettivamente risolto ?
l0b0,

Non so se time bash -lc truefunziona correttamente qui dal momento che truefinisce prima, ~0.1squindi non fonte nulla. Comunque time source /etc/bash_completionriporta ~ 0.17s qui ed è circa il tempo che devo aspettare per PS1apparire.
cYrus

2
Ingegnoso! In spiegazione, i comandi trap mancano USR1a alla fine.
Fish Monitor,

Con SIGUSR, il gestore del segnale non viene richiamato fino a quando non premo invio al prompt della shell. C'è una pausa a quel punto mentre corre. Sono passato a SIGQUIT e sembra funzionare bene.
Jon Nalley,

5

Dovresti usare l'ultima versione (2.0) di bash_completion. Se stai usando Debian, è in wheezy, ma non ha dipendenze da nessun altro pacchetto wheezy, quindi puoi installarlo su una compressione senza problemi.

L'ultima versione carica il completamento in modo dinamico al volo, quindi ha diviso il tempo di caricamento rapido per me di almeno 10 volte.


1

È possibile utilizzare un segnaposto durante il caricamento dei completamenti; dovrebbe bastare a ingannare i tuoi occhi. Questo ovviamente funziona solo se il tempo necessario source /etc/bash_completionè inferiore al tempo necessario per digitare ed emettere il primo comando di shell, altrimenti verrà ritardato.

L'idea è di echeggiare un falso PS1, procurarsi i completamenti e infine cancellare il terminale.

Supponiamo che tu lo PS1sia \u@\h:\w\$, potrebbero scrivere qualcosa del tipo:

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

Dove:

  • 2J cancella il terminale;
  • H sposta il cursore nell'angolo in alto a destra.

Nota: è possibile verificare se l'utente è root e utilizzare #invece che $per coerenza:

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

Nota: la rimozione \e[2Jevita lo sfarfallio ma lascerà i caratteri spazzatura se il segnaposto è più lungo del prompt effettivo.

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.