¿Por qué ~ / .bash_profile no se obtiene al abrir un terminal?

175

Problema

Tengo una máquina virtual Ubuntu 11.04 y quería configurar mi entorno de desarrollo Java. Hice lo siguiente

  1. sudo apt-get install openjdk-6-jdk
  2. Se agregaron las siguientes entradas a ~ / .bash_profile

    export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
    
    export PATH=$PATH:$JAVA_HOME/bin
  3. Guarde los cambios y salga

  4. Abre una terminal nuevamente y escribe lo siguiente

    echo $JAVA_HOME   (blank)
    echo $PATH        (displayed, but not the JAVA_HOME value)
  5. No pasó nada, como si la exportación de JAVA_HOME y su adición a la RUTA nunca se hicieran.

Solución

Tuve que ir a ~ / .bashrc y agregar la siguiente entrada al final del archivo

#Source bash_profile to set JAVA_HOME and add it to the PATH because for some reason is not being picked up
. ~/.bash_profile

Preguntas

  1. ¿Por qué tuve que hacer eso? Pensé que bash_profile, bash_login o profile en ausencia de esos dos se ejecutan primero antes de bashrc.
  2. ¿Era en este caso mi terminal un shell sin inicio de sesión ?
  3. Si es así, ¿por qué al hacer su después de la terminal y poner la contraseña no ejecutó el perfil donde también había configurado las exportaciones mencionadas anteriormente?
Viriato
fuente

Respuestas:

224

~/.bash_profilesolo se obtiene de bash cuando se inicia en modo de inicio de sesión interactivo. Esto suele ocurrir solo cuando inicia sesión en la consola ( Ctrl+ Alt+ F1.. F6) o cuando se conecta a través de ssh.

Cuando inicie sesión gráficamente, se ~/.profileobtendrá específicamente del script que inicia gnome-session (o el entorno de escritorio que esté utilizando). Por ~/.bash_profilelo tanto, no se obtiene nada cuando inicia sesión gráficamente.

Cuando abre una terminal, la terminal comienza a bash en modo interactivo (sin inicio de sesión), lo que significa que se generará ~/.bashrc.

El lugar correcto para colocar estas variables de entorno es ~/.profile, y el efecto debería ser evidente la próxima vez que inicie sesión.

Abastecerse ~/.bash_profilede ~/.bashrces la solución incorrecta. Se supone que es al revés; ~/.bash_profiledebe fuente ~/.bashrc.

Consulte DotFiles para obtener una explicación más detallada, que incluye algunos antecedentes de por qué es así.

(En una nota al margen, al instalar openjdk a través de apt, el paquete debe configurar los enlaces simbólicos, de modo que realmente no necesite configurar JAVA_HOMEo cambiar PATH)

geirha
fuente
66
Descubrí que al abrir una Terminal desde la barra lateral en Ubuntu 12, el archivo ~ / .profile no se carga.
jcollum
3
@jcollum Eso está bien. .profilesolo debe obtenerse cuando inicie sesión.
geirha
2
oh, abrir una terminal no es lo mismo que iniciar sesión ... Estaba pensando en iniciar sesión en la terminal .
jcollum
2
Tenga en cuenta que .profilebash ignora si .bash_profileexiste. Vea mi respuesta aquí y man bashpara más detalles.
terdon
3
@terdon, sí, pero bash no está involucrado al iniciar sesión gráficamente, por lo que va directo .profile.
geirha
48

Puede verificar si su shell Bash se inicia como un shell de inicio de sesión ejecutando:

shopt login_shell

Si la respuesta es offque no está ejecutando un shell de inicio de sesión.

Lea la sección de invocación del manual de Bash sobre cómo Bash lee (o no lee) diferentes archivos de configuración.

Extracto de man bash:

Cuando se invoca bash como un shell de inicio de sesión interactivo, o como un shell no interactivo con la --login opción, primero lee y ejecuta comandos del archivo /etc/profile, si ese archivo existe. Después de leer ese archivo, busca ~/.bash_profile, ~/.bash_loginy ~/.profile, en ese orden, y lee y ejecuta órdenes desde el primero que existe y es legible.

supor otro lado, tampoco inicia un shell de inicio de sesión de forma predeterminada, debe indicarle que lo haga mediante la --loginopción

lgarzo
fuente
99
Muchas gracias por el comando shotp login_shell . ¡¡Increíble!!
Viriato
27

Creo que vale la pena mencionar que puede cambiar el valor predeterminado de gnome-terminal para usar un shell de inicio de sesión (es decir, bash -l) editando las preferencias del perfil.

vaya a Editar -> Preferencias de perfil -> pestaña Título y comando, marque la opción "Ejecutar comando como un shell de inicio de sesión"

kisoku
fuente
1
¿Cuáles son las desventajas de habilitar esta configuración?
2017
2
@chris solo estás cargando código un poco más de código del necesario en muchas ocasiones. Probablemente no importa si ~/.bash_profileestá evaluando realmente rápido, lo que probablemente sea el caso. Una buena cosa para verificar es descartar cualquier llamada a otros procesos que generalmente son bastante costosos.
vaab
14

Si abre una terminal o ejecuta suel shell no se ejecuta como un shell de inicio de sesión sino como un shell interactivo normal. Entonces se lee ~/.bashrcpero no ~/.bash_profile. Puede ejecutar sucon la -lopción de hacer que ejecute su shell como un shell de inicio de sesión.

Cuando está trabajando con una GUI, el shell generalmente nunca se ejecuta como un shell de inicio de sesión, por lo que generalmente está bien poner todo lo que necesita ~/.bashrc.

Florian Diesch
fuente
1
Eso es lo que hice y funcionó, pero comprueba lo que dice el chico de abajo, sugiere que es una mala idea ponerlo en bashrc y ponerlo en el perfil. .... Hola, las dos cosas funcionan, muchas gracias.
Viriato
4

TL; DR

En la configuración clásica recomendada de ubuntu, ~/.bash_profilese evalúa solo en ocasiones específicas. Y tiene sentido.

Pon tus cosas adentro ~/.bashrc, serán evaluadas cada vez.

Ok, quiero entender, ¿por qué tiene sentido?

Puntos clave para entender lo que está sucediendo:

  • Todos los procesos en Linux tienen y usan variables de entorno
  • las variables de entorno se heredan
  • Por lo tanto, establecerlos una vez en el padre de todo su proceso es suficiente (especialmente si requiere algo de tiempo de cálculo).
  • el padre de todo su proceso generalmente se inicia después de iniciar sesión en su dispositivo (proporcione sus credenciales).
  • Hay cosas que quizás desee hacer solo una vez cuando inicie sesión en su computadora (verifique si hay correo nuevo, por ejemplo ...).

Por lo tanto, el tiempo de "inicio de sesión" suele ser:

  • En el modo consola, cuando inicie sesión (con Ctrl-Alt F1) o mediante ssh, como el shell será el padre de todo el proceso, cargará su ~/.bash_profile.
  • En modo gráfico, cuando abra su sesión, el primer proceso ( gnome-sessionpara ubuntu clásico) se encargará de leer
    .profile.

Ok, entonces, ¿dónde poner mis cosas?

Es bastante complejo, la historia completa está aquí . Pero aquí hay un descuido que es bastante común para los usuarios de ubuntu. Entonces considerando eso:

  • usas bashshell,
  • tiene una ~/.bash_profiley sigue la recomendación de agregar la carga de ~/.bashrcen su ~/.bash_profilepara obtener al menos un archivo que se evalúa sea cual sea el mecanismo de invocación .

Esta es una sugerencia rápida de dónde colocar las cosas.

  • ~ / .bashrc (se evalúa en todas las ocasiones , siempre que siga la recomendación)

    Para una variable de entorno de evaluación rápida y código para su uso de línea de comandos solo para usuarios y bash (alias, por ejemplo). El bashismo es bienvenido.

    Se carga sobre sí mismo sobre:

    • crear una nueva ventana / panel de shell en sesiones gráficas.
    • vocación bash
    • screennuevo panel o pestaña. (no tmux!)
    • cualquier instancia de bash en un cliente de consola gráfica ( terminator/ gnome-terminal...) si no marca la opción "ejecutar comando como shell de inicio de sesión".

    Y se cargará en cualquier otra ocasión gracias a la recomendación previa.

  • ~ / .bash_profile (se evalúa solo en ocasiones específicas )

    Para variables de entorno de evaluación lenta y código para sus procesos de sesión de consola y solo de usuario . El bashismo es bienvenido. Se carga en:

    • inicio de sesión de consola (Ctrl-Alt F1),
    • ssh inicia sesión en esta máquina,
    • tmuxnuevo panel o ventanas (configuración predeterminada), ( screen¡ no !)
    • llamadas explícitas de bash -l,
    • cualquier instancia de bash en un cliente de consola gráfica ( terminator/ gnome-terminal...) solo si marca la opción "ejecutar comando como shell de inicio de sesión".
  • ~ / .profile (se evalúa solo en sesión gráfica)

    Para variables de entorno de evaluación lenta y sin bashism para sus procesos de sesión gráfica y solo para usuarios . Se carga al iniciar sesión en su interfaz gráfica de usuario.

vaab
fuente
En las ocasiones en que bash carga un archivo de perfil, se cargará .profilesi .bash_profileno existe.
Muru
Muchas gracias por una explicación clara. Ayuda a los novatos como yo. En Mac Mojave, si pongo variables en ~ / .bashrc y hago source, y luego si lo hago env, no veo el conjunto de variables env (intenté cerrar iTerm y volver a abrir). Pero noté que cuando instalé Android Studio y otras aplicaciones, todos esos entornos se instalaron /.bash_profile. Entonces, cuando agregué /.bash_profile, funcionó como un encanto. ¿Porqué es eso?
sofs1