Variables d'environnement dans bash_profile ou bashrc?

Apr 05 2012

J'ai trouvé cette question [blog]: Différence entre .bashrc et .bash_profile très utile mais après avoir vu la réponse la plus votée (très bien d'ailleurs), j'ai d'autres questions. Vers la fin de la réponse correcte la plus votée, je vois la déclaration comme suit:

Notez que vous pouvez voir ici et là des recommandations pour soit mettre des définitions de variables d'environnement dans ~ / .bashrc, soit toujours lancer des shells de connexion dans les terminaux. Les deux sont de mauvaises idées.

  1. Pourquoi est-ce une mauvaise idée (je n'essaye pas de me battre, je veux juste comprendre)?

  2. Si je veux définir une variable d'environnement et l'ajouter au PATH (par exemple JAVA_HOME) où ce serait le meilleur endroit pour placer l'entrée d'exportation? dans ~ / .bash_profile ou ~ / .bashrc ?

  3. Si la réponse à la question numéro 2 est ~ / .bash_profile , alors j'ai deux autres questions:

    3.1. Que mettriez-vous sous ~ / .bashrc ? seulement des alias?

    3.2. Dans un shell sans connexion, je crois que le ~ / .bash_profile n'est pas "ramassé". Si l'exportation de l'entrée JAVA_HOME était dans bash_profile, pourrais-je exécuter des commandes javac et java ? Les trouverait-il sur le CHEMIN? Est-ce la raison pour laquelle certains messages et forums suggèrent de définir JAVA_HOME et autres sur ~ / .bashrc ?

    Merci d'avance.

Réponses

28 geekosaur Apr 06 2012 at 04:36

Dans un système moderne, il n'est pas particulièrement courant de se heurter aux cas où cela compte, mais cela arrive. (En particulier, si vous utilisez des opérations shell sous une forme vimtelle que :r !commandou en ligne !<motion>command.)

Que mettriez-vous sous ~ / .bashrc? seulement des alias?

Vous mettez des éléments ~/.bashrcqui ne seraient pas hérités automatiquement par les sous-shell; cela signifie principalement des alias et des fonctions, bien que parfois vous ayez des paramètres variables que vous ne voulez pas voir visibles en dehors du shell (c'est très rare). On pourrait soutenir que ceux-ci devraient être exportés d'une manière ou d'une autre, mais diverses tentatives expérimentales se sont heurtées à des problèmes de compatibilité en essayant de les cacher dans l'environnement et ont pour la plupart été abandonnées.

Si je veux définir une variable d'environnement et l'ajouter au PATH (par exemple JAVA_HOME) où ce serait le meilleur endroit pour placer l'entrée d'exportation? dans ~ / .bash_profile ou ~ / .bashrc?

Vous mettez les paramètres d'environnement ~/.bash_profileafin qu'ils reçoivent des paramètres initiaux sains. Parfois, vous voudrez les remplacer (souvent cela est fait par des environnements complexes tels que Matlab ou Cadence); si vous mettez les paramètres d'environnement, les ~/.bashrcshells exécutés à partir de ces environnements perdront les personnalisations de l'environnement et les choses risquent de ne pas fonctionner correctement en conséquence. Ceci s'applique également si vous utilisez un package tel que modules , virtualenv , rvm , etc. pour gérer plusieurs environnements de développement; mettre vos paramètres ~/.bashrcsignifie que vous ne pouvez pas exécuter l'environnement souhaité à partir de votre éditeur, mais sera à la place forcé dans le système par défaut.

Dans un shell sans connexion, je crois que le ~ / .bash_profile n'est pas "ramassé".

C'est correct; vous voulez normalement que le shell initial soit un shell de connexion et que tous les shells démarrés sous celui-ci ne soient pas des shells de connexion. Si le shell initial n'est pas un shell de connexion, vous n'aurez pas de PATHparamètres par défaut ou d'autres paramètres (y compris votre JAVA_HOMEexemple).

La plupart des environnements de bureau lancés à partir de gestionnaires d'affichage (c'est-à-dire la grande majorité des connexions graphiques) ne configurent pas d'environnement de connexion pour l'ensemble du bureau, vous êtes donc obligé d'exécuter le shell initial dans les terminaux en tant que shell de connexion. Cela pose un certain nombre de problèmes (notamment que le PATHet tel disponible pour les programmes exécutés à partir de panneaux, par exemple, n'est pas configuré correctement, car le panneau n'est pas un terminal et n'a pas fonctionné ~/.bash_profile), mais constitue un compromis raisonnable étant donné que ce n'est pas toujours possible pour s'exécuter correctement ~/.bash_profiledans l'environnement non interactif au début d'une session lancée par un gestionnaire d'affichage, en fonction de son contenu. Il est parfois suggéré de placer les paramètres d'environnement au ~/.bashrclieu de configurer un shell de connexion à la place; comme indiqué plus haut, cela fonctionne aussi longtemps que vous n'avez pas besoin de passer outre cet environnement, et les causes bizarres une fois que vous casses faire besoin de le faire.

J'ai récemment aidé à diagnostiquer un problème comme celui-ci sur OS X où un utilisateur qui avait placé des paramètres ~/.bashrcpuis plus tard a commencé à utiliser rvmet perlbrew a vu un comportement étrange, car les environnements configurés par les deux ont été «annulés» par des ~/.bashrcéditeurs internes et sudo(ce qui sur OS X , contrairement à Linux, propage l'utilisateur $HOMEpour qu'il ~/.bashrcsoit exécuté par le shell racine). Avant d'essayer d'utiliser ces environnements, il n'y avait aucun problème; en commençant à les utiliser, ils ont été déconcertés par la perte inattendue de leurs paramètres.

2 bubu Apr 06 2012 at 04:28

pour être honnête, il y a peu de différence de nos jours malgré ce que le gourou avait à dire.

le problème derrière cela est que de nos jours, nous nous connectons graphiquement plutôt que via un shell de connexion. dans le passé, nous les utilisateurs d'Unix aimons voir un court rapport de ce qui se passe sur un serveur immédiatement après la connexion - puis nous allons démarrer X par ligne de commande - ces rapports nécessitent souvent un certain temps pour être générés (par exemple 10-20 secondes). et puis nous ne voulons pas voir la même chose quand nous commençons par exemple xterm. donc la différence.

de nos jours, je ne pense pas que la distinction soit importante maintenant. Je pense que ces jours-ci, si vous source bashrc dans bash_profile, personne ne pourrait vous en vouloir.

notez que cela ne s'applique pas à macos x (chaque terminal.app démarré est un shell de connexion)

1 hute37 Nov 20 2015 at 10:14

Eh bien, à propos des "Logins graphiques", cela dépend du * DM que vous utilisez ...

Avec GDM (Gnome 3.18) j'ai ceci:

/ 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"

Ainsi, ~ / .profile obtient la source lors de la connexion en utilisant / bin / sh et non / bin / bash

Il y a deux cas

  1. / bin / sh est lié à / bin / bash mais fonctionne en mode "POSIX / Bourne"
  2. / bin / sh est / bin / dash (debian / ubuntu). Le plus rapide mais avec moins de fonctionnalités (support ShellShock;) )

Ainsi, le profil / bin / sh est ~ / .profile et non ~ / .bash_profile, ~ / .zprofile

Ce fichier doit être utilisé pour les paramètres " indépendants du shell" , comme les variables de chemin et d'environnement.

AUCUN programme exécutable pour une interaction utilisateur avec connexion uniquement ne devrait être mais ici (vérification du courrier, fortune, etc.)

les ~ /.* rc ne sont destinés qu'aux sessions "interactives" (alias par exemple ...)

Il y a une différence entre bash et zsh pour les shells de connexion interactifs

bash sources uniquement .bash_profile, tandis que zsh sources dans l'ordre:

  1. ~ / .zprofile
  2. ~ / .zshrc
  3. ~ / zlogin (ici les alias définis dans ~ / .zshrc sont disponibles. en cas de shells "interactif" + "login"

La bonne façon de faire ~ / .bash_profile a été répondu ici:

Différence entre .bashrc et .bash_profile

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

Pour activer le test (et le profilage), vous pouvez utiliser ce

~ / .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`
# ------------------------------------------------

puis, pour tester:

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

Donc RVM / virtualenv devrait aller dans ~ / .profile, à mon humble avis

Mais cela NE FONCTIONNE PAS , parfois ...

Par exemple, virualenvwrapper ne fonctionne que si le shell exécutant Xsession est un bash "original" (exportation BASH_VERSION)

Si vous êtes sur un système de tableau de bord , la variable d'environnement et le paramètre de chemin fonctionnent, mais la définition de la fonction virualenvwrapper ne fonctionne pas car le script n'est pas compatible POSIX.

Le script ne donne aucune erreur mais il se termine sans aucune définition "workon" .

Vous pouvez donc définir l'environnement disponible dans ~ / .profile , juste pour activer l'exécution correcte de python à partir du client démarré directement à partir de 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

Mais pour virualenvwrapper, vous avez deux alternatives:

  1. source-le dans ~ / .bash_profile ou ~ / .zprofile (ou ~ / .zlogin) lorsque le terminal agit comme shell de connexion
  2. inclure le script dans ~ / .bashrc ou ~ / zshrc

Cela signifie que les clients X (emacs par exemple) doivent être démarrés depuis le shell du terminal et non depuis le graphique!

"Je ne peux pas obtenir aucune satisfaction ..."