Pourquoi ~ / .bash_profile n'est pas recherché lors de l'ouverture d'un terminal?

176

Problème

J'ai une machine virtuelle Ubuntu 11.04 et je voulais configurer mon environnement de développement Java. J'ai fait comme suit

  1. sudo apt-get install openjdk-6-jdk
  2. Ajout des entrées suivantes dans ~ / .bash_profile

    export JAVA_HOME=/usr/lib/jvm/java-6-openjdk
    
    export PATH=$PATH:$JAVA_HOME/bin
  3. Enregistrez les modifications et quittez

  4. Ouvrez à nouveau un terminal et tapez ce qui suit

    echo $JAVA_HOME   (blank)
    echo $PATH        (displayed, but not the JAVA_HOME value)
  5. Rien ne s'est passé, comme si l'exportation de JAVA_HOME et son ajout au PATH n'étaient jamais terminés.

Solution

Je devais aller à ~ / .bashrc et ajouter l'entrée suivante vers la fin du fichier

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

Des questions

  1. Pourquoi devais-je faire ça? Je pensais que bash_profile, bash_login ou profil en l’absence de ces deux-là s’exécutait d’abord avant bashrc.
  2. Mon terminal était-il dans ce cas un shell sans connexion ?
  3. Si tel est le cas, pourquoi lorsque vous faites su après le terminal et que vous mettez le mot de passe, il n’exécute pas le profil dans lequel j’ai également défini les exportations susmentionnées?
Viriato
la source

Réponses:

225

~/.bash_profileprovient uniquement de bash lorsqu'il est démarré en mode de connexion interactive. Cela se produit généralement uniquement lorsque vous vous connectez à la console ( Ctrl+ Alt+ F1.. F6) ou que vous vous connectez via ssh.

Lorsque vous vous connectez graphiquement, ~/.profilele code qui lance gnome-session (ou l’environnement de bureau que vous utilisez) permet de rechercher spécifiquement les sources. Donc, ~/.bash_profilen’est pas recherché du tout lorsque vous vous connectez graphiquement.

Lorsque vous ouvrez un terminal, celui-ci démarre en mode interactif (sans connexion), ce qui signifie qu'il se source ~/.bashrc.

Le bon endroit pour mettre ces variables d’environnement est à ~/.profilel’intérieur et l’effet devrait être évident lors de votre prochaine connexion.

Sourcing ~/.bash_profilefrom ~/.bashrcest la mauvaise solution. C'est censé être l'inverse. ~/.bash_profiledevrait source ~/.bashrc.

Voir DotFiles pour une explication plus complète, incluant un historique de pourquoi c'est comme ça.

(Remarque: lors de l'installation d'Openjdk via apt, les liens symboliques doivent être configurés par le paquet, de sorte que vous n'avez pas vraiment besoin de les définir JAVA_HOMEou de les modifier. PATH)

geirha
la source
6
J'ai constaté que lors de l'ouverture d'un terminal à partir de la barre latérale dans Ubuntu 12, le fichier ~ / .profile n'est pas chargé.
jcollum
3
@ jcollum C'est bien. .profilene devrait provenir que de la connexion.
geirha
2
oh, ouvrir un terminal, ce n'est pas la même chose que de se connecter… Je pensais me connecter au terminal .
Jcollum
2
Gardez à l'esprit que .profilebash ignore si elle .bash_profileexiste. Voir ma réponse ici et man bashpour plus de détails.
terdon
3
@terdon, oui, mais bash n'est pas impliqué dans la connexion graphique, donc ça va directement .profile.
geirha
48

Vous pouvez vérifier si votre shell Bash est lancé en tant que shell de connexion en lançant:

shopt login_shell

Si la réponse est que offvous n'exécutez pas un shell de connexion.

Lisez la section sur l' invocation du manuel Bash pour savoir comment Bash lit (ou ne lit pas) différents fichiers de configuration.

Extrait de man bash:

Lorsque bash est appelé en tant que shell de connexion interactif ou en tant que shell non interactif avec l' --login option, il commence par lire et exécuter les commandes du fichier /etc/profile, si ce fichier existe. Après avoir lu ce fichier, il recherche ~/.bash_profile, ~/.bash_loginet ~/.profile, dans cet ordre, et lit et exécute les commandes de la première qui existe et est lisible.

suD'autre part, ne lance pas non plus un shell de connexion par défaut, vous devez le lui dire en utilisant l' --loginoption.

lgarzo
la source
9
Merci beaucoup pour la commande shotp login_shell . Impressionnant!!
Viriato
27

Je pense qu'il vaut la peine de mentionner que vous pouvez changer la valeur par défaut de gnome-terminal pour utiliser un shell de connexion (par exemple, bash -l) en modifiant les préférences de profil.

allez dans Edition -> Préférences de profil -> Titre et commande, cochez la case "Exécuter la commande en tant que shell de connexion"

Kisoku
la source
1
Quels sont les inconvénients pour activer ce paramètre?
terminé
2
@ chris, vous chargez juste un peu plus de code que nécessaire dans de nombreuses occasions. Peu importe si votre ~/.bash_profileévaluation est très rapide, ce qui est probablement le cas. Une bonne chose à vérifier est de chasser tous les appels à d’autres processus qui sont généralement assez coûteux.
vaab
14

Si vous ouvrez un terminal ou exécutez sule shell, celui-ci n’est pas exécuté en tant que shell de connexion, mais en tant que shell interactif normal. Donc, il lit ~/.bashrcmais pas ~/.bash_profile. Vous pouvez exécuter suavec l' -loption pour le faire exécuter votre shell en tant que shell de connexion.

Lorsque vous travaillez avec une interface graphique, le shell n’est généralement jamais exécuté en tant que shell de connexion ~/.bashrc;

Florian Diesch
la source
1
C’est ce que j’ai fait et que cela a fonctionné, mais vérifiez ce que le type en bas dit, il suggère que c’est une mauvaise idée de le mettre dans bashrc et de le mettre à la place. .... Hé dans les deux sens, merci beaucoup.
Viriato
4

TL; DR

Dans la configuration classique recommandée d'ubuntu, ~/.bash_profileest évalué uniquement à des occasions spécifiques. Et c'est logique.

Mettez vos affaires ~/.bashrc, elles seront évaluées à chaque fois.

Ok, je veux comprendre, pourquoi cela a-t-il un sens?

Points clés pour comprendre ce qui se passe:

  • tous les processus sur Linux ont et utilisent des variables d' environnement
  • les variables d'environnement sont héritées
  • il suffit donc de les placer une fois sur le père de tous vos processus (surtout si cela nécessite du temps de calcul).
  • Le père de tous vos processus est généralement lancé une fois que vous vous êtes connecté à votre appareil (indiquez vos informations d'identification).
  • il y a des choses que vous ne voudrez peut-être faire qu'une seule fois lorsque vous vous connecterez à votre ordinateur (recherchez les nouveaux messages, par exemple ...).

Donc, le temps de "connexion" est typiquement:

  • En mode console, lorsque vous vous connectez (avec Ctrl-Alt F1) ou via ssh, car le shell sera le père de tous les processus, il chargera votre fichier ~/.bash_profile.
  • En mode graphique, lorsque vous ouvrez votre session, le premier processus ( gnome-sessionpour ubuntu classique) sera chargé de lire
    .profile.

Ok, alors où mettre mes affaires?

C'est assez complexe, l' histoire complète est ici . Mais voici un récit assez commun pour les utilisateurs d'ubuntu. Donc, considérant que:

  • vous utilisez bashshell,
  • vous avez ~/.bash_profileet suivez la recommandation d’ajouter le chargement de ~/.bashrcdans votre ~/.bash_profileafin d’obtenir au moins un fichier qui sera évalué quel que soit le mécanisme d’invocation .

Ceci est une suggestion rapide de l'endroit où placer les choses.

  • ~ / .bashrc (est évalué dans toutes les occasions , à condition que vous suiviez la recommandation)

    Pour évaluation rapide variable d'environnement et le code pour votre utilisateur uniquement et bash seule utilisation en ligne de commande (alias , par exemple). les bashismes sont les bienvenus.

    Il se charge sur lui-même sur:

    • créer une nouvelle fenêtre / volet shell dans les sessions graphiques.
    • appel bash
    • screennouveau volet ou onglet. (pas tmux!)
    • toute instance bash dans un client de console graphique ( terminator/ gnome-terminal...) si vous ne cochez pas l' option "exécuter la commande en tant que shell de connexion".

    Et il sera chargé dans toutes les autres occasions grâce à la recommandation préalable.

  • ~ / .bash_profile (Obtient évalué dans une occasion spécifique seulement )

    Pour variable d’environnement d’ évaluation lente et code pour vos processus de session utilisateur et console uniquement . les bashismes sont les bienvenus. Il est chargé sur:

    • connexion à la console (Ctrl-Alt F1),
    • ssh se connecte à cette machine,
    • tmuxnouveau volet ou nouvelle fenêtre (paramètres par défaut), (pas screen!)
    • appels explicites de bash -l,
    • toute instance bash dans un client de console graphique ( terminator/ gnome-terminal...) uniquement si vous cochez l'option "Exécuter la commande en tant que shell de connexion".
  • ~ / .profile (Gets évalué uniquement en session graphique)

    Pour les variables d'environnement à évaluation lente et sans nohisme pour vos processus de session utilisateur uniquement et graphiques . Il se charge lors de la connexion dans votre interface graphique.

vaab
la source
Lorsque bash charge un fichier de profil, il se chargera .profiles’il .bash_profilen’existe pas.
Muru
Merci beaucoup pour une explication claire. ça aide les débutants comme moi. Dans Mac Mojave, si je mets des variables dans ~ / .bashrc et que je le source, puis si je ne le envfais pas, je ne vois pas les variables env définies (j'ai essayé de fermer iTerm et de le rouvrir). Mais j’ai remarqué que lorsque j’ai installé Android studio et d’autres applications, tous ces paramètres étaient configurés /.bash_profile. Alors, quand j'ai ajouté /.bash_profileça a fonctionné comme un charme. Pourquoi donc?
sofs1