web-dev-qa-db-fra.com

Variables d'environnement dans bash_profile ou bashrc?

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 au fait) 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 mettre des définitions de variable d’environnement dans ~/.bashrc ou toujours lancer des shells de login dans des terminaux. Les deux sont de mauvaises idées.

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

  2. Si je veux définir une variable d'environnement et l'ajouter à la variable PATH (par exemple, Java_HOME), il s'agirait du meilleur endroit pour insérer l'entrée d'exportation? dans ~/.bash_profile ou ~/.bashrc ?

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

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

    3.2. Dans un shell non connecté, je crois que le ~/.bash_profile n'est pas "récupéré". Si l'exportation de 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 ses semblables de manière à ~/.bashrc ?

    Merci d'avance.

34
Viriato

Sur un système moderne, il n’est pas particulièrement courant de se retrouver dans les cas où cela compte, mais cela arrive. (En particulier, si vous utilisez des opérations Shell dans vim, telles que :r !command ou le formulaire !<motion>command en ligne.)

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

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

Si je veux définir une variable d'environnement et l'ajouter à la variable PATH (par exemple, Java_HOME), il s'agirait du meilleur endroit pour insérer l'entrée d'exportation? dans ~/.bash_profile ou ~/.bashrc?

Vous définissez les paramètres d’environnement dans ~/.bash_profile pour leur attribuer des paramètres initiaux sains. Parfois, vous voudrez les remplacer (souvent par des environnements complexes tels que Matlab ou Cadence); Si vous définissez les paramètres d'environnement dans ~/.bashrc, les shells exécutés à partir de ces environnements perdront la personnalisation des environnements, ce qui risque de ne pas fonctionner correctement. 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 dans ~/.bashrc signifie que vous ne pouvez pas exécuter l'environnement souhaité à partir de votre éditeur, mais que vous serez forcé à utiliser les paramètres par défaut du système.

Dans un shell non connecté, je pense que le fichier ~/.bash_profile n'est pas "récupéré".

C'est correct; vous voulez normalement que le shell initial soit un shell de connexion et que tous les shell commencés sous celui-ci soient et non comme des shell de connexion. Si le shell initial n'est pas un shell de connexion, vous n'aurez pas de valeur par défaut PATH ou divers autres paramètres (y compris votre exemple Java_HOME).

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 devez donc exécuter le shell initial dans les terminaux en tant que shell de connexion. Cela pose un certain nombre de problèmes (notamment le fait que la PATH et celle disponible pour les programmes exécutés à partir de panneaux, par exemple, n’est pas configurée correctement, car le panneau n’est pas un terminal et n’a pas exécuté ~/.bash_profile), mais constitue un compromis raisonnable, étant donné qu’il Il est toujours possible d'exécuter correctement ~/.bash_profile dans l'environnement non interactif au début d'une session démarrée par un gestionnaire d'affichage, en fonction de son contenu. Il est parfois suggéré de placer les paramètres d'environnement dans ~/.bashrc au lieu de configurer un shell de connexion. Comme indiqué ci-dessus, cela fonctionne tant que vous n'avez pas besoin de remplacer cet environnement, et provoque des ruptures inhabituelles une fois que vous faites devez le faire.

J'ai récemment aidé à diagnostiquer un problème comme celui-ci sur OS X: un utilisateur qui avait défini les paramètres dans ~/.bashrc puis commencé plus tard à utiliser rvm et perlbrew a constaté un comportement étrange, car les environnements configurés par les deux étaient "annulés" par ~/.bashrc dans les éditeurs et Sudo (qui sous OS X, contrairement à Linux, propage le $HOME de l'utilisateur de sorte que son ~/.bashrc soit exécuté par le shell racine). Avant d'essayer d'utiliser ces environnements, il n'y avait pas de problème; en commençant à les utiliser, ils ont été déroutés par la perte inattendue de leurs réglages.

25
geekosaur

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

le problème derrière tout cela est qu’aujourd’hui, nous nous connectons de manière graphique plutôt que via un shell de connexion. Dans le passé, nous, les utilisateurs Unix, aimons voir un bref rapport sur ce qui se passe sur un serveur immédiatement après la connexion. Nous démarrons ensuite 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 alors 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 sourcez 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)

2
bubu

Eh bien, à propos des "connexions 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 est identifié lors de la connexion en utilisant /bin/sh et non /bin /frapper

Il y a deux cas

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

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

Ce fichier doit être utilisé pour les paramètres "Shell agnostic" , tels que les variables de chemin et d’environnement.

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

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

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

sources bash uniquement. profil_bash, tandis que les sources zsh dans l’ordre:

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

La bonne façon de faire ~/.bash_profile a été traitée 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 cette

~/.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, IMHO

Mais cela NE FONCTIONNE PAS , parfois ...

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

Si vous êtes sur un système avec tiret , 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 conforme à POSIX .

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

Vous pouvez donc définir l'environnement actuel dans ~/.profile , juste pour permettre l'exécution correcte du 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. le source dans ~/.bash_profile ou ~/.zprofile (ou ~/.zlogin) lorsque le terminal agit comme un login
  2. inclure le script dans ~/.bashrc ou ~/zshrc

Cela signifie que les clients X (emacs par exemple) doivent être lancés à partir du terminal Shell et non du graphique!

"Je ne peux obtenir aucune satisfaction ..."

1
hute37