Pourquoi mon ~ / .bash_profile ne fonctionne-t-il pas?

35

J'utilise Linux Mint. Mon shell de connexion ( cat /etc/passwd | grep myUserName) est bash.

Après avoir démarré mon environnement de bureau graphique et exécuté un émulateur de terminal à partir de celui-ci, je constate que la .bash_profilesource n’est pas source (les vars d’environnement qui y exportsont édités ne sont pas définis). Mais si je me connecte à partir d'une console de texte ( ctrl+ alt+ F1) ou que je lance manuellement à bash -lpartir de l'émulateur de terminal, cela .bash_profilefonctionne correctement.

Est-ce que je me trompe quand je pense que cela .bash_profiledevrait provenir du démarrage de X et que tous exportles vars modifiés devraient être disponibles dans le terminal, à partir de X?

Post-scriptum Tout placer dans .bashrcet source à partir de .bash_profilen'est pas une bonne idée ( https://stackoverflow.com/questions/902946/ ): les éléments d'environnement ne doivent être importés qu'une seule fois.

AntonioK
la source

Réponses:

39

Le fichier ~/.bash_profileest lu par bash lorsqu'il s'agit d'un shell de connexion. C'est ce que vous obtenez lorsque vous vous connectez en mode texte.

Lorsque vous vous connectez sous X, les scripts de démarrage sont exécutés par /bin/sh. Sur Ubuntu et Mint, /bin/shc'est dash , pas bash. Dash et bash ont tous deux les mêmes fonctionnalités principales, mais dash s'en tient à ces fonctionnalités essentielles pour être rapides et compacts, tandis que bash ajoute de nombreuses fonctionnalités au prix de ressources supplémentaires. Il est courant d’utiliser dash pour les scripts qui n’ont pas besoin des fonctionnalités supplémentaires et de bash pour une utilisation interactive (bien que zsh possède de nombreuses fonctionnalités plus agréables ).

La plupart des combinaisons de gestionnaire d'affichage (le programme dans lequel vous tapez votre nom d'utilisateur et mot de passe) et l' environnement de bureau lire ~/.profiledes scripts de connexion /etc/X11/Xsession, /usr/bin/lightdm-session, /etc/gdm/Xsessionou selon le cas. Alors mettez vos définitions de variables d’environnement dans ~/.profile. Veillez à utiliser uniquement la syntaxe prise en charge par dash.

Alors, que devriez-vous mettre où?

  • Une bonne .bash_profilecharge .profile, et charge .bashrcsi le shell est interactif.

    . ~/.profile
    if [[ $- == *i* ]]; then . ~/.bashrc; fi
  • Dans .profile, définissez les définitions de variable d’environnement et d’autres paramètres de session tels que ulimit.

  • Dans .bashrc, mettez les paramètres interactifs bash tels que les alias, les fonctions, la complétion, les raccourcis clavier (qui ne sont pas dans .inputrc),…

Voir aussi Différence entre shell de connexion et shell de non-connexion? et Alternative à .bashrc .

Gilles, arrête de faire le mal
la source
1
beaucoup de choses apprises d'une seule réponse :)
mtk
16

.bash_profileest le script de configuration de démarrage de bash. Il n'existe pas de norme obligeant X à la source .bash_profile.

Ce à quoi vous pensez, c'est plutôt .profile. À l'origine, il s'agissait du fichier de configuration de démarrage du bourne shell (sh). Aujourd'hui, de nombreuses distributions ont leur environnement de bureau configuré en source .profile. Notez que ce n’est pas non plus une norme, mais cela semble être une convention.

Auparavant, Debian utilisait une source .profilede connexion graphique ( page wiki de 2013 ), mais pas maintenant ( page wiki de 2016 ).

Arch sources .xprofilelors de la connexion graphique ( page wiki à partir de 2013 ).

Ubuntu déconseillait d’utiliser .profile( page wiki à partir de 2013 ) maintenant, il ne décourage plus ( page wiki à partir de 2016 ).


Concernant votre autre question: Pourquoi mon ~ / .bash_profile ne fonctionne-t-il pas? C'est le comportement attendu.

Le comportement, en bref, est le suivant:

  • bash a démarré en tant que shell de connexion interactif: reads ~/.profile
  • bash a démarré en tant que shell interactif sans connexion: lit ~/.bashrc

Pour plus de détails, voir ma réponse à une question similaire dans askubuntu: https://askubuntu.com/questions/132276/configure-gnome-terminal-to-start-bash-as-a-login-shell-doesnt-read-bashrc / 132319 # 132319

lesmana
la source
1
Cela est correct en partie, mais «toujours lire ~/.bashrc» est un mauvais conseil: vous ne devriez lire que .bashrcdepuis un shell interactif . Vous avez oublié le problème fondamental qui est que lors de la connexion sous X, il n’existe pas d’instance de connexion de bash (dans la plupart des combinaisons d’environnement de gestionnaire d’affichage et de bureau, y compris évidemment AntonioK).
Gilles, arrête de faire le mal '25
Merci pour votre avis. J'espère avoir suffisamment mis à jour ma réponse pour résoudre vos plaintes. En ce qui concerne mon conseil de "toujours lire .bashrc", je voulais toujours parler d'un shell interactif. J'ai clarifié cette partie. J'espère que ce n'est plus trompeur.
Lesmana
2
" Ubuntu déconseille spécifiquement d'utiliser .profile( lien ) " Le wiki décourageait une fois (absurdement) cela; ça a été corrigé. (Note /etc/profilene reste découragé pour des missions échelle du système, de préférence pour l' ajout de scripts /etc/profile.d.) Par utilisateur les .profilefichiers sont maintenant présentés comme l' une des méthodes recommandées pour fixer l' environnement par l' utilisateur des variables: « les fichiers appropriés pour les paramètres variables de l' environnement qui devrait affecter seulement Les utilisateurs particuliers (plutôt que le système dans son ensemble) sont ~ / .pam_environment et ~ / .profile . "
Eliah Kagan
La page liée à propos de Debian spécifie que Debian ne lit pas~/.profile pour la connexion graphique et ~/.xsessionrcdoit être utilisée à la place.
Karora
Merci d'avoir remarqué. la page wiki a été mise à jour. J'ai lié aux versions telles qu'elles étaient au moment de la réponse.
Lesmana
2

Dans votre question, vous vous référez à https://stackoverflow.com/questions/902946/ comme recommandant de ne pas utiliser une source, lorsque la réponse acceptée indique:

  • Placer ma configuration PATH dans un fichier .profile (car j’utilise parfois d’autres shells)
  • Mettre mes alias et fonctions Bash dans mon fichier .bashrc
  • Puis utilisez ceci [EDITED: snip code-comments]:

    .bash_profile:

    #!/bin/bash
    # echo "Loading ${HOME}/.bash_profile"
    source ~/.profile # Get the paths
    source ~/.bashrc  # get aliases

Tout mettre en place .profilene fonctionnait pas pour moi sous Linux Mint. L'utilisation .bashrca bien fonctionné.

serv-inc
la source
2

Quelques problèmes se posent lorsque vous essayez de recharger / source le fichier ~ / .profile. [Cela concerne Ubuntu linux - dans certains cas, les détails des commandes seront différents]

  1. Est-ce que vous l'exécutez directement dans un terminal ou dans un script?
  2. Comment exécutez-vous cela dans un script?

Un d. 1)

L'exécuter directement dans le terminal signifie qu'aucun sous-shell ne sera créé. Vous pouvez donc utiliser l'une des deux commandes suivantes:

source ~/.bash_profile

ou

. ~/.bash_profile

Dans les deux cas, l'environnement sera mis à jour avec le contenu du fichier .profile.

Ad 2) Vous pouvez lancer n’importe quel script bash en appelant

sh myscript.sh 

ou

. myscript.sh

Dans le premier cas, cela créera un sous-shell qui n’affectera pas les variables d’environnement de votre système et celles-ci ne seront visibles que par le processus du sous-shell. Une fois la commande de sous-shell terminée, aucune des exportations, etc. ne sera appliquée. CECI EST UNE ERREUR COMMUNE ET PERMET À BEAUCOUP DE DÉVELOPPEURS DE PERDRE BEAUCOUP DE TEMPS.

Pour que vos modifications appliquées dans votre script aient un effet sur l'environnement global, vous devez exécuter le script avec

.myscript.sh

commander.

Afin de vous assurer que votre script n'est pas exécuté dans un sous-marin, vous pouvez utiliser cette fonction. (Encore une fois, l'exemple concerne le shell Ubuntu)

#/bin/bash

preventSubshell(){
  if [[ $_ != $0 ]]
  then
    echo "Script is being sourced"
  else
    echo "Script is a subshell - please run the script by invoking . script.sh command";
    exit 1;
  fi
}

J'espère que cela efface certains des malentendus communs! : D bonne chance!

twboc
la source
0

La solution simple consiste à faire du terminal un terminal de connexion. Pour le terminal Gnome sous "Tile and Command" du profil par défaut, vous pouvez cocher la case "Exécuter la commande en tant que shell de connexion". Cet article explique la différence entre un shell de connexion et un autre.

dériveur
la source