¿Por qué la finalización de bash se carga tan lentamente en OS X?

16

No entiendo por qué la finalización de bash se carga tan lentamente en mi MacBook Pro.

Hice lo siguiente en mi ~/.bash_profile:

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

el tiempo de ejecución para bash_completion generalmente es> 2 segundos.

Me resulta realmente molesto cuando estoy trabajando en el terminal, lo que me obliga a abrir constantemente nuevas pestañas.

¿Hay alguna manera de almacenar esto o algo así?

(Tenga en cuenta que estoy usando iTerm2 y esto es igualmente lento en el terminal original en Mac también).

desaparecido
fuente
Eso no debería estar sucediendo. ¿Estoy correcto si usas la finalización bash de MacPort?
slhck
¿Cómo se ve el archivo que carga?
Daniel Beck
@slhck: Sí, de hecho estoy usando la finalización de bash de macport
desapareció el
@Daniel: Todo está bien, excepto esto. Perfilé casi todas las líneas.
desaparecido el
55
Experimento la misma lentitud y estoy usando Homebrew.
Brice

Respuestas:

10

Versión corta: eliminar una sola línea del /usr/local/etc/bash_completiontiempo reducido para abrir una nueva pestaña de diez segundos a un cuarto de segundo. Sigue leyendo para más detalles.

Estoy usando bash-complete de homebrew y encontré el mismo problema. Me llevaba más de diez segundos cargar los scripts de finalización de bash cada vez que abría un terminal.

La mayor parte de ese tiempo, parece estar ocupado por una sola línea en la have()función: una llamada typepara determinar si está instalado un programa de línea de comandos.

Con la have()función predeterminada y todos los scripts de finalización de bash proporcionados en su lugar, se necesitarían 10.561 s para cargar los scripts (informados mediante el prefijo timea la . /opt/local/etc/bash_completionlínea en mi .bash_profilearchivo).

Después de comentar la PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&línea de mi /usr/local/etc/bash_completionscript (salir de la have=yeslínea, abrir un nuevo terminal toma solo 0.258s. Este tiempo podría reducirse aún más eliminando los scripts de terminación innecesarios (enlaces simbólicos) del /usr/local/etc/bash_completion.ddirectorio.

No sé por qué la llamada typetarda tanto. Estoy investigando eso a continuación.

Una posible desventaja de este enfoque es que provocará que las funciones de finalización de bash se carguen en la memoria aunque no las use. La have()función verifica si hay un comando o aplicación instalada. Si no es así, el script de finalización generalmente decide no molestarse en cargarse porque no será de utilidad.

Por el momento, estoy contento con la compensación, pero continuaré explorando el typeproblema a medida que tenga tiempo. Actualizaré mi respuesta si encuentro una mejor solución.

Godbyk
fuente
Para mí, comentar esta línea reduce el tiempo de 50 ms, de 230 ms a 180 ms. Por supuesto, nunca lo tuve tan mal en primer lugar. 👍
Edward Anderson
Esto solo redujo unos 60 ms, por lo que no he mantenido la solución. No tengo tiempos de espera de diez segundos, sino unos 2 segundos, lo cual es un poco molesto.
danemacmillan
7

Para cualquiera que llegue a la conclusión de que los tiempos de inicio para los nuevos shells en MacOS son demasiado lentos para ellos, esta es la solución .

Acabo de descubrir que, de hecho, hay dos paquetes que se pueden instalar a través de brew. He estado instalando el bash-completionpaquete durante años, y nunca me molesté en cuestionarlo, aunque en ese momento pasé de Bash 3, a 4, a ahora 5. Sin embargo, de vez en cuando, volvía a visitar el problema. , a menudo tropezando con esta discusión de StackOverflow.

¡Hay otro paquete bash-completion@2!

¿Cual es la diferencia? bash-completiones para Bash versión 3.2. bash-completion@2es para Bash versión 4.1+ y 5.

Al eliminar el bash-completionpaquete anterior e instalarlo bash-completion@2, los tiempos de inicio de mi shell se han reducido de 605 ms a 244 ms. Esa es una gran mejora de velocidad.

Sospecho que muchos de nosotros estamos cometiendo este mismo error, ya que las brew infoestadísticas muestran que el primero tiene toneladas de instalaciones, mientras que el segundo tiene muy pocas:

ingrese la descripción de la imagen aquí

Cabe señalar que la respuesta actual elegida menciona comentar algunas líneas, lo que proporciona solo una ligera mejora en los tiempos de inicio (si usa el bash-completionpaquete anterior, que muchos probablemente son), pero no tiene ningún impacto en el nuevo bash-completion@2paquete: este nuevo paquete es rápido pase lo que pase Eso significa que no se requieren hacks.

TL; DR:

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

Recuerde actualizar la ruta de origen al archivo de finalización en su archivo .bashrco .bash_profile.

Fuentes:


Como un tema algo relacionado, uso mucho la rcloneutilidad, por lo que está instalada. También tiene el archivo de finalización más grande que he visto . Eliminarlo reduce los tiempos de inicio de mi shell a ~ 120 ms, que es muy rápido.


Editar:

Para cualquiera que quiera los detalles técnicos que explican este problema, he escrito sobre ello en detalle en los foros de Homebrew . Para resumir, la razón que bash-completion@2es mucho más rápida es porque se escribió para que ya no cargue con entusiasmo todos los archivos de finalización; en su lugar, carga un archivo de finalización a pedido o, como lo describe el autor, los carga de manera no entusiasta .

danemacmillan
fuente
Creo que la versión predeterminada de Bash en macOS sigue siendo la v3.2. No creo que se envíe con Bash v4.2. ¿Tiene una referencia donde dice que macOS viene con Bash v4.2 +?
nwinkler
1
@nwinkler Estarías en lo correcto. Estoy desconcertado por qué mencioné eso, porque MacOS todavía incluye version 3.2.57(1)-release (x86_64-apple-darwin18). Gracias por señalar eso; He eliminado la línea de mi publicación.
danemacmillan
1
Desconcertante, lo sé ... ¡Gracias por actualizar tu respuesta!
nwinkler
3

Con la idea que me dio la respuesta de Godbyk, descubrí que mi variable PATH tenía algunos directorios que no tenían binarios o que no existían, por lo que su eliminación se aceleró significativamente. En otras palabras, esta es la RUTA que tuve en mi bashrc:

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

Y luego lo cambié a:

PATH="$GOPATH/bin:$PATH"

Esto se debió a que la havefunción en la finalización de bash, buscó cada comando, y tenía demasiados directorios inútiles que iban a ser visitados para cada uno de esos binarios, eliminándolos para acelerarlo.

Farid Nouri Neshat
fuente
También logré cambiar el tiempo de carga de alrededor de 5 segundos a menos de 1 segundo eliminando rutas que no existen de mi variable de entorno PATH.
juriejan
0

Tuve el mismo problema. Unos simples trucos de depuración me llevaron a la causa raíz.

Primero, habilítelo DEBUG modepara que pueda ver lo que está sucediendo:

export BASH_COMPLETION_DEBUG=true

Esto permite la impresión detallada en la consola, para que pueda ver el último comando. Ahora puede ejecutar el script en segundo plano y verá lo que está sucediendo.

. /opt/local/etc/bash_completion &

No tome de la PID, que luego puede rastrear con pso pstree:

pstree -p <the PID>:

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

Como puede ver, comenzó algunos comandos relacionados con el óxido, que llevaban años.

Eliminar temporalmente /opt/boxen/homebrew/etc/bash_completion.d/cargoresolvió mis síntomas.

Matthew Fellows
fuente
-1

Si está ejecutando MacPorts> = 2.1.2 y Mountain Lion, parece que bash_profileestá equivocado. Siga las instrucciones sobre ¿Cómo hacer que git-completar.bash funcione en Mac OS X? . Supongo que eso podría acelerar la finalización automática.

Otra solución sería intentar instalar el autocompletado a través de Fink o Homebrew. Si eso no funciona, puedes probar con otro shell por completo. Descubrí que Fish Shell es excepcional cuando se trata de autocompletar (listo para usar). Aunque la versión 2 todavía está en beta, lo recomendaría encarecidamente.

awek
fuente
-1

Voy a adivinar que tu fiesta es demasiado vieja. Estoy ejecutando stock bash que vino con Mountain Lion y esto es lo que veo:

$ 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.
ilustración numérica
fuente
No veo tener este comando de puerto. :( ¿Cómo puedo saber qué software de finalización de pestaña git se está ejecutando en mi Mac?
Dean Hiller
@DeanHiller Esta respuesta se refiere al administrador de paquetes Macports, que proporciona el comando de puerto. La aplicación de finalización de bash de Macports será más nueva que la proporcionada con OS X.
Matt S