Variables de entorno en bash_profile o bashrc?

36

He encontrado esta pregunta [blog]: la diferencia entre .bashrc y .bash_profile es muy útil, pero después de ver la respuesta más votada (muy buena por cierto) tengo más preguntas. Hacia el final de la respuesta correcta más votada, veo la siguiente declaración:

Tenga en cuenta que puede ver recomendaciones aquí y allá para colocar definiciones de variables de entorno en ~ / .bashrc o siempre iniciar shells de inicio de sesión en terminales. Ambas son malas ideas.

  1. ¿Por qué es una mala idea (no estoy tratando de pelear, solo quiero entender)?

  2. Si quiero establecer una variable de entorno y agregarla a la RUTA (por ejemplo, JAVA_HOME), ¿dónde sería el mejor lugar para colocar la entrada de exportación? en ~ / .bash_profile o ~ / .bashrc ?

  3. Si la respuesta a la pregunta número 2 es ~ / .bash_profile , entonces tengo dos preguntas más:

    3.1. ¿Qué pondrías debajo de ~ / .bashrc ? solo alias?

    3.2. En un shell sin inicio de sesión, creo que el ~ / .bash_profile no se está "recogiendo". Si la exportación de la entrada JAVA_HOME fuera en bash_profile, ¿podría ejecutar los comandos javac y java ? ¿Los encontraría en el CAMINO? ¿Es esa la razón por la cual algunas publicaciones y foros sugieren configurar JAVA_HOME y similares a ~ / .bashrc ?

    Gracias por adelantado.

Viriato
fuente

Respuestas:

26

En un sistema moderno, no es especialmente común encontrarse con los casos en los que es importante, pero sucede. (En particular, si utiliza operaciones de shell en vimtal como :r !commando en la forma en línea !<motion>command).

¿Qué pondrías debajo de ~ / .bashrc? solo alias?

Pones cosas ~/.bashrcque las subcapas no heredarían automáticamente; esto significa alias y funciones, principalmente, aunque a veces tiene configuraciones variables que no desea que sean visibles fuera del shell (esto es muy raro). Se podría argumentar que deberían exportarse de alguna manera, pero varios intentos experimentales se han topado con problemas de compatibilidad al tratar de ocultarlos dentro del entorno y en su mayoría han sido abandonados.

Si quiero establecer una variable de entorno y agregarla a la RUTA (por ejemplo, JAVA_HOME), ¿dónde sería el mejor lugar para colocar la entrada de exportación? en ~ / .bash_profile o ~ / .bashrc?

Pones la configuración del entorno ~/.bash_profilepara que se les otorgue una configuración inicial sensata. A veces querrás anularlos (a menudo esto se hace en entornos complejos como Matlab o Cadence); si coloca la configuración del entorno ~/.bashrc, los shells que se ejecutan dentro de esos entornos perderán las personalizaciones de los entornos y, como resultado, las cosas pueden no funcionar correctamente. Esto también se aplica si usa un paquete como módulos , virtualenv , rvm , etc. para administrar múltiples entornos de desarrollo; poner su configuración ~/.bashrcsignifica que no puede ejecutar el entorno que desea desde su editor, sino que se verá forzado a la configuración predeterminada del sistema.

En un shell sin inicio de sesión, creo que el ~ / .bash_profile no se está "recogiendo".

Esto es correcto; normalmente desea que el shell inicial sea un shell de inicio de sesión y que los shells que se inicien bajo ese no sean shells de inicio de sesión. Si el shell inicial no es un shell de inicio de sesión, no tendrá una configuración predeterminada PATHo varias otras (incluido su JAVA_HOMEejemplo).

La mayoría de los entornos de escritorio lanzados desde los administradores de pantalla (es decir, la gran mayoría de los inicios de sesión gráficos) no configuran un entorno de inicio de sesión para todo el escritorio, por lo que se ve obligado a ejecutar el shell inicial en los terminales como un shell de inicio de sesión. Esto causa una serie de problemas (en particular, que los PATHprogramas disponibles que se ejecutan desde, por ejemplo, paneles no están configurados correctamente, porque el panel no es un terminal y no se ha ejecutado ~/.bash_profile), pero es un compromiso razonable dado que no siempre es posible para ejecutarse correctamente ~/.bash_profileen el entorno no interactivo al comienzo de una sesión iniciada por un administrador de pantalla, dependiendo de su contenido. A veces se sugiere colocar la configuración del entorno en~/.bashrcen lugar de configurar un shell de inicio de sesión; como se discutió anteriormente, esto funciona siempre que no necesite anular ese entorno y cause roturas extrañas una vez que lo necesite.

Recientemente ayudé a diagnosticar un problema como este en OS X, donde un usuario que había colocado la configuración y ~/.bashrcluego comenzó a usarlo rvmy perlbrew vio un comportamiento extraño, porque los entornos configurados por los dos fueron "deshechos" por ~/.bashrceditores internos y sudo(que en OS X , a diferencia de Linux, propaga el usuario $HOMEpara que ~/.bashrcel shell raíz lo ejecute). Antes de intentar usar esos entornos, no había problema; al comenzar a usarlos, quedaron desconcertados por la inesperada pérdida de su configuración.

geekosaur
fuente
1
Creo que lo entiendo, podría tener que leerlo más veces para internalizarlo más, pero estoy concluyendo lo siguiente. En entornos empresariales para tener un control más preciso de los shells personalizados sin efectos secundarios del global, es una buena práctica poner las variables de entorno en ~ / .bash_profile . En un entorno personal como Ubuntu o Linux Mint para tener la RUTA configurada correctamente, debería configurarla en ~ / .bashrc (o incluso en / etc / profile ). ¿Estoy en lo correcto?
Viriato
Tiene menos que ver con los entornos empresariales que con si solo eres un usuario o un desarrollador; A los sistemas les gustan modulesy rvmson herramientas de desarrollo, al igual que Matlab y Cadence para definiciones algo diferentes de "desarrollador". Desarrollo sencillo tampoco requiere de ellos, pero cuando se necesita para la prueba contra múltiples versiones de Ruby, Perl, Python o entonces usted realmente quiere algo así rvm, perlbrewy virtualenv(respectivamente) en torno a la ayuda a mantener todo en orden.
geekosaur
2

Para ser honesto, hay poca diferencia en estos días a pesar de lo que el gurú tenía que decir.

El problema detrás de esto es que hoy en día iniciamos sesión gráficamente en lugar de hacerlo a través de un shell de inicio de sesión. En el pasado, a los usuarios de Unix les gusta ver un breve informe de lo que está sucediendo en un servidor inmediatamente después de iniciar sesión, luego comenzaremos X por línea de comando; este informe a menudo requiere algo de tiempo para generar (por ejemplo, 10-20 segundos). y luego no queremos ver lo mismo cuando empezamos, por ejemplo, xterm. De ahí la diferencia.

Hoy en día no creo que la distinción sea importante ahora. Creo que en estos días si obtienes bashrc en bash_profile nadie podría culparte.

tenga en cuenta que esto no se aplica a macos x (cada terminal.app iniciado es un shell de inicio de sesión)

bubu
fuente
No estoy exactamente seguro de entender completamente, pero en el trabajo cuando inicio sesión a través de ssh que es un shell de inicio de sesión, luego bash_profile y bashrc se obtienen, así que supongo que en ese caso no importa. Pero si inicio sesión gráficamente (¿qué significa eso)? como iniciar sesión en mi ubuntu personal?
Viriato
De acuerdo con la respuesta de @bubu aquí: cualquier configuración que ~/.bash_profileno sea fuente ~/.bashrces bastante difícil de trabajar y está rota. Las aplicaciones de terminal gráficas significan que es más simple simplemente obtener ~ / .bashrc y poner toda la configuración allí.
RichVel
1

Bueno, sobre "Inicios de sesión gráficos", depende de qué * DM uses ...

Con GDM (Gnome 3.18) tengo esto:

/ etc / gdm / Xsession

#!/bin/sh   <= *important*

...

# First read /etc/profile and .profile
test -f /etc/profile && . /etc/profile
test -f "$HOME/.profile" && . "$HOME/.profile"
# Second read /etc/xprofile and .xprofile for X specific setup
test -f /etc/xprofile && . /etc/xprofile
test -f "$HOME/.xprofile" && . "$HOME/.xprofile"

Entonces, ~ / .profile se obtiene al iniciar sesión usando / bin / sh y no / bin / bash

Hay dos casos

  1. / bin / sh está vinculado a / bin / bash pero se ejecuta en modo "POSIX / Bourne"
  2. / bin / sh es / bin / dash (debian / ubuntu). Más rápido pero con menos funciones (soporte ShellShock;) )

Entonces el perfil / bin / sh es ~ / .profile y no ~ / .bash_profile, ~ / .zprofile

Este archivo debe usarse para configuraciones "agnósticas de shell" , como las variables de ruta y entorno.

NO debe haber ningún programa ejecutable para la interacción del usuario de inicio de sesión solo aquí (verificación de correo, fortuna, etc.)

los ~ /.* rc son solo para sesiones "interactivas" (alias por ejemplo ...)

Hay una diferencia entre bash y zsh para shells de inicio de sesión interactivo

fuentes bash solo .bash_profile, mientras que las fuentes zsh en el orden:

  1. ~ / .zprofile
  2. ~ / .zshrc
  3. ~ / zlogin (aquí los alias definidos en ~ / .zshrc están disponibles. en caso de shells "interactivos" + "login"

Aquí se respondió la forma correcta de hacer ~ / .bash_profile :

Diferencia entre .bashrc y .bash_profile

if [ -r ~/.profile ]; then . ~/.profile; fi
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac

Para habilitar la prueba (y la creación de perfiles), puede usar esto

~ / .bash_profile:

#!/bin/bash

# ------------------------------------------------
export _DOT_BASH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------

if [ -f ~/.profile ] ; then
    . ~/.profile
fi

case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac

# ------------------------------------------------
export _DOT_BASH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------

~ / .zprofile:

#!/bin/zsh

# ------------------------------------------------
export _DOT_ZSH_PROFILE_0=`date  --rfc-3339=ns`
# ------------------------------------------------

if [ -f ~/.profile ] ; then
    . ~/.profile
fi

# no need to source, zsh already handle ~/.zshrc

###case "$-" in *i*) if [ -r ~/.zshrc ]; then . ~/.zshrc; fi;; esac

# ------------------------------------------------
export _DOT_ZSH_PROFILE_1=`date  --rfc-3339=ns`
# ------------------------------------------------

entonces, para probar:

chsh -s /bin/bash

ssh localhost
env

exit

ssh localhost env

ssh -t localhost bash -i -c env


chsh -s /bin/zsh

ssh localhost
env

exit

ssh localhost env

ssh -t localhost bash -i -c env

Entonces RVM / virtualenv debería ir en ~ / .profile, en mi humilde opinión

Pero esto NO FUNCIONA , a veces ...

Por ejemplo, virualenvwrapper funciona solo si el shell que ejecuta Xsession es un bash "original" (exportando BASH_VERSION)

Si está en un sistema de tablero , la variable de entorno y la configuración de ruta funcionan, pero la definición de la función virualenvwrapper no funciona porque el script no es compatible con POSIX.

El script no da ningún error, pero termina sin ninguna definición de "workon" .

Por lo tanto, puede configurar el entorno en cuestión en ~ / .profile , solo para habilitar la ejecución correcta de Python desde el cliente iniciado directamente desde X:

export VIRTUAL_ENV="/home/mike/var/virtualenvs/myvirtualenv"
export PATH="$VIRTUAL_ENV/bin:$PATH"
unset PYTHON_HOME

https://gist.github.com/datagrok/2199506

https://www.bountysource.com/issues/9061991-setting-up-your-computer-virtualenvwrapper-linux-all

Pero para virualenvwrapper tienes dos alternativas:

  1. fuente en ~ / .bash_profile o ~ / .zprofile (o ~ / .zlogin) cuando el terminal actúa como shell de inicio de sesión
  2. incluir el script en ~ / .bashrc o ~ / zshrc

¡Esto significa que los clientes X (por ejemplo, emacs) deberían iniciarse desde el terminal y no desde el gráfico!

"No puedo obtener ninguna satisfacción ..."

hute37
fuente
Una historia completamente diferente es la ejecución de servicios con systemd. Algunas alternativas posibles son: escribir una secuencia de comandos de contenedor , definir el entorno en el archivo de definición de "servicio" , volcar el entorno en un archivo "env" para obtenerlo en un shell principal. Las cosas se vuelven más complicadas con RVM / virtualenv ...
hute37