Descubra qué scripts ejecuta bash al inicio

15

Después de iniciar un terminal bash, noté que la variable PATH contiene entradas duplicadas. Mi terminal inicia un shell de inicio de sesión , por lo que ~/.bash_profilese obtiene, seguido de ~/.profiley ~/.bashrc. Solo en ~/.profilecreo las entradas de rutas que están duplicadas.

Para ser pedante, este es el orden en el que se obtienen los archivos que DEBEN obtenerse:

Sourced /etc/profile
Sourced /etc/bash.bashrc
Sourced .bash_profile
Sourced .profile
Sourced .bashrc

Antes de que alguien marque esto como un duplicado de "La variable PATH contiene duplicados", sigue leyendo.

Al principio pensé que esto tenía que ver con el ~/.profileorigen dos veces, así que hice que el archivo escribiera en un archivo de registro cada vez que se obtuvo, y sorprendentemente solo registró una entrada, lo que me dice que solo se obtuvo una vez. Aún más sorprendente es el hecho de que cuando comento las entradas que estaban en ~/.profile, las entradas todavía aparecen en la PATHvariable. Esto me ha llevado a tres conclusiones, una de las cuales se descartó rápidamente:

  1. Bash ignora los comentarios de bash válidos y aún ejecuta el código comentado
  2. Hay un script que lee ~/.profilee ignora cualquier código que imprima una salida (el archivo de registro, por ejemplo)
  3. Hay otra copia de mi ~/.profileque está siendo obtenida en otro lugar

El primero, rápidamente concluí que no era el caso debido a algunas pruebas rápidas. La segunda y tercera opciones son donde necesito ayuda.

¿Cómo recopilo un registro de scripts que se ejecutan cuando se inicia mi terminal? Utilicé echolos archivos que verifiqué para saber si provienen de bash, pero necesito encontrar un método concluyente que rastree la ejecución hasta el punto en que el terminal esté listo para que empiece a escribir en él.

Si lo anterior no es posible, ¿alguien puede sugerirme dónde más puedo mirar para ver qué scripts se están ejecutando ?


Referencia futura

Este es el script que ahora uso para agregar a mi ruta:

function add_to_path() {
    for path in ${2//:/ }; do
        if ! [[ "${!1}" =~ "${path%/}" ]]; then # ignore last /
            new_path="$path:${!1#:}"
            export "$1"="${new_path%:}" # remove trailing :
        fi
    done
}

Lo uso así:

add_to_path 'PATH' "/some/path/bin"

El script verifica si la ruta ya existe en la variable antes de anteponerla.

Para los usuarios de zsh, puede usar este equivalente:

function add_to_path() {
    for p in ${(s.:.)2}; do
        if [[ ! "${(P)1}" =~ "${p%/}" ]]; then
            new_path="$p:${(P)1#:}"
            export "$1"="${new_path%:}"
        fi
    done
}

Editar 28/8/2018

Una cosa más que encontré que podría hacer con este script es también arreglar la ruta. Entonces, al comienzo de mi .bashrcarchivo, hago algo como esto:

_temp_path="$PATH"
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin'
add_to_path 'PATH' "$_temp_path"
unset _temp_path

Depende de usted con qué PATHdebe comenzar. Examine PATHprimero para decidir.

smac89
fuente
Bash solo lee ~/.profile si ~/.bash_profileno existe ...
jasonwryan
@jasonwryan, fuente ~/.profiley ~/.bashrcde~/.bash_profile
smac89

Respuestas:

30

Si su sistema tiene strace, puede enumerar los archivos abiertos por el shell, por ejemplo, utilizando

echo exit | strace bash -li |& grep '^open'

( -lisignifica shell de inicio de sesión interactivo; utilícelo solo -ipara un shell interactivo sin inicio de sesión).

Esto mostrará una lista de archivos que el shell abrió o intentó abrir. En mi sistema, son los siguientes:

  1. /etc/profile
  2. /etc/profile.d/*(varios scripts en /etc/profile.d/)
  3. /home/<username>/.bash_profile (esto falla, no tengo ese archivo)
  4. /home/<username>/.bash_login (esto falla, no tengo ese archivo)
  5. /home/<username>/.profile
  6. /home/<username>/.bashrc
  7. /home/<username>/.bash_history (historial de líneas de comando; esto no es un script)
  8. /usr/share/bash-completion/bash_completion
  9. /etc/bash_completion.d/* (varios scripts que proporcionan funcionalidad de autocompletado)
  10. /etc/inputrc (define las asociaciones de teclas; esto no es un script)

Úselo man stracepara más información.

AlexP
fuente
Gracias por tu aporte, pero creo que hay algo muy mal con mi bash. Ejecutar echo $0en el terminal da en -bashlugar de lo esperado bash. ¿Tienes alguna otra sugerencia para esto?
smac89
3
@ smac89: Eso es normal para un shell de inicio de sesión. Bash se comporta como un shell de inicio de sesión cuando el primer carácter de $0es un guión -, o cuando se invoca con la opción -l.
AlexP
OK, eso es un alivio. Ejecuté el comando que dio y la salida parece realmente complicada, pero, sin embargo, todos los archivos mostrados no contienen las entradas duplicadas. Esto me lleva a pensar que las entradas duplicadas suceden cuando inicio sesión por primera vez en mi cuenta, es decir, algo está originando inicialmente las entradas en ese archivo y se vuelve a hacer cuando abro el terminal. En realidad creo que podría ser eso. Cuando inicio sesión en mi cuenta, las entradas se obtienen y, nuevamente, cuando abro el terminal, el proceso se repite. ¿Eso suena posible?
smac89
¿Por qué no depuras a la antigua usanza, poniendo echo PATH=\""$PATH"\"al principio y al final de .profiley .bashrc? ¿Y por qué no haces lo que todos hacen y configuras la RUTA completamente o, si agregas un directorio, guardas echo ":$PATH:" | grep -q ":/path/to/dir:" || export PATH="$PATH:/path/to/dir":?
AlexP
44
Usar sudo bash -c "echo exit|dtruss bash -li|& less|grep '^open'"en macOS. (solo reemplace stracecon dtruss)
Max Coplan