Question Différence entre .bashrc et .bash_profile


Quelle est la différence entre .bashrc et .bash_profile et lequel dois-je utiliser?


401
2017-09-02 14:40


origine


Voir aussi cette question similaire à ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile - Stefan Lasiewski
Si vous voulez une explication plus complète qui implique également .profile, regardez cette question: superuser.com/questions/789448/ - Flimm
Cette réponse couvre également certains aspects stackoverflow.com/questions/415403/... - Sergey Voronezhskiy


Réponses:


Traditionnellement, lorsque vous vous connectez à un système Unix, le système lance un programme pour vous. Ce programme est un shell, c’est-à-dire un programme conçu pour lancer d’autres programmes. C'est un shell de ligne de commande: vous démarrez un autre programme en tapant son nom. Le shell par défaut, un shell Bourne, lit les commandes de ~/.profile quand il est appelé en tant que shell de connexion.

Bash est un shell de type Bourne. Il lit les commandes de ~/.bash_profile quand il est appelé en tant que shell de connexion, et si ce fichier n'existe pas¹, il essaie de lire ~/.profile au lieu.

Vous pouvez appeler un shell directement à tout moment, par exemple en lançant un émulateur de terminal dans un environnement graphique. Si le shell n'est pas un shell de connexion, il ne lit pas ~/.profile. Lorsque vous démarrez bash en tant que shell interactif (c'est-à-dire, ne pas exécuter de script), il lit ~/.bashrc (sauf lorsqu’il est appelé en tant que shell de connexion, il ne lit que ~/.bash_profile ou ~/.profile.

Donc:

  • ~/.profile est l'endroit où placer des éléments qui s'appliquent à l'ensemble de votre session, tels que les programmes que vous souhaitez démarrer lorsque vous vous connectez (mais pas les programmes graphiques, ils entrent dans un fichier différent) et les définitions de variables d'environnement.

  • ~/.bashrc est l'endroit où placer des éléments qui s'appliquent uniquement à bash lui-même, tels que les définitions d'alias et de fonctions, les options de shell et les paramètres d'invite. (Vous pouvez aussi y placer des raccourcis clavier, mais pour bash, ils entrent normalement dans ~/.inputrc.)

  • ~/.bash_profile peut être utilisé à la place de ~/.profile, mais il n'est lu que par bash, pas par un autre shell. (Il s’agit surtout d’un problème si vous souhaitez que vos fichiers d’initialisation fonctionnent sur plusieurs ordinateurs et que votre shell de connexion ne les bascule pas sur tous.) C’est un endroit logique pour inclure ~/.bashrc si le shell est interactif Je recommande le contenu suivant dans ~/.bash_profile:

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

Sur les univers modernes, il y a une complication supplémentaire liée à ~/.profile. Si vous vous connectez dans un environnement graphique (c'est-à-dire si le programme sur lequel vous tapez votre mot de passe s'exécute en mode graphique), vous n'obtenez pas automatiquement un shell de connexion qui lit ~/.profile. En fonction du programme de connexion graphique, du gestionnaire de fenêtres ou de l’environnement de bureau que vous exécutez ensuite, et de la manière dont votre distribution a configuré ces programmes, votre ~/.profile peut ou peut ne pas être lu. Si ce n'est pas le cas, il existe généralement un autre endroit où vous pouvez définir des variables d'environnement et des programmes à lancer lorsque vous vous connectez, mais il n'y a malheureusement aucun emplacement standard.

Notez que vous pouvez voir ici et là des recommandations pour mettre des définitions de variables d'environnement dans ~/.bashrc ou toujours lancer des shells de connexion dans les terminaux. Les deux sont de mauvaises idées. Le problème le plus courant avec l’une ou l’autre de ces idées est que vos variables d’environnement ne seront définies que dans les programmes lancés via le terminal, et non dans les programmes lancés directement avec une icône, un menu ou un raccourci clavier.

¹  Pour être complet, sur demande: si .bash_profile n'existe pas, bash essaie aussi .bash_loginavant de revenir à .profile. N'hésitez pas à l'oublier.  


471
2017-09-02 19:23



+1 pour un bon post. Merci également pour l'ajout de la section sur "login graphique vs shell de connexion" ... J'ai eu le problème où je pensais ~ / .profile exécuterait toujours pour graphique / shell ... mais il ne s'exécute pas lorsque l'utilisateur se connecte via une connexion graphique. Merci d'avoir résolu ce mystère. - Trevor Boyd Smith
@Gilles: Pouvez-vous expliquer plus en détail, avec des exemples, pourquoi exécuter un shell de connexion dans chaque terminal est une mauvaise idée? Est-ce seulement un problème avec Linux de bureau? (Je suppose que sous OS X Terminal exécute un shell de connexion à chaque fois, et je n'ai jamais remarqué d'effets secondaires (bien que j'utilise habituellement iTerm). Mais je ne peux pas penser à beaucoup de variables d'environnement en dehors de un terminal. (Peut-être HTTP_PROXY?)) - iconoclast
@Brandon Si vous exécutez un shell de connexion dans chaque terminal, cela remplacera les variables d'environnement fournies par l'environnement. Dans les situations de tous les jours, vous pouvez vous en sortir, mais il vous arrivera tôt ou tard, lorsque vous souhaitez configurer différentes variables dans un terminal (par exemple, pour essayer une version différente d'un programme): Le shell de connexion remplace vos paramètres locaux. - Gilles
La déclaration ~/.bash_profile peut être utilisé à la place de ~/.profile, mais vous devez également inclure ~/.bashrc si le shell est interactif est trompeur car ce sont des problèmes orthogonaux. Peu importe si vous utilisez ~/.bash_profile ou ~/.profile vous devez inclure ~/.bashrc dans celui que vous utilisez si vous souhaitez que les paramètres soient appliqués dans le shell de connexion. - Piotr Dobrogost
@Gilles Sure, mais la façon dont la phrase est formulée dans la réponse suggère que le besoin d'inclure ~/.bashrc a quelque chose à voir avec le choix ~/.bash_profile au lieu de ~/.profile ce qui n'est pas vrai Si quelqu'un inclut ~/.bashrc dans tout type de script provenant de la connexion (ici soit ~/.bash_profile ou ~/.profile) est parce qu'il veut des paramètres de ~/.bashrc à appliquer au shell de connexion de la même manière qu'ils sont appliqués au shell non connecté. - Piotr Dobrogost


De ceci article court

Selon la page de manuel de bash,   .bash_profile est exécuté pour la connexion   shells, tandis que .bashrc est exécuté pour   coquilles interactives sans connexion.

Qu'est-ce qu'un shell de connexion ou de non connexion?

Lorsque vous vous connectez (par exemple: tapez nom d'utilisateur et   mot de passe) via la console, soit   assis physiquement à la machine quand   démarrage, ou à distance via ssh:   .bash_profile est exécuté pour configurer   choses avant la commande initiale   rapide.

Mais si vous êtes déjà connecté   votre machine et ouvrez un nouveau terminal   window (xterm) dans Gnome ou KDE,   alors .bashrc est exécuté avant le   invite de commande de fenêtre. .bashrc est aussi   exécuter lorsque vous démarrez une nouvelle instance de bash   en tapant / bin / bash dans un terminal.


50
2017-09-02 14:54



Légères mises à jour: «Executed» est probablement un terme légèrement trompeur, ils sont tous les deux issus. Les sons exécutés ressemblent à un script, fork / exec yadda yadda. Il est exécuté dans le contexte du shell actuel Plus important encore, .bashrc est exécuté beaucoup plus souvent. Il est exécuté sur chaque script bash exécuté, ainsi que si vous ne possédez pas de fichier .bash_profile. En outre, en fonction de la configuration de vos xterms, vous pouvez créer un shell qui source .bash_profile - Rich Homolka


Auparavant, lorsque les modems n'utilisaient pas les pseudo-tty, et que les modems y accédaient si lentement, vous pouviez voir chaque lettre imprimée sur votre écran, l'efficacité était primordiale. Pour aider quelque peu l'efficacité, vous aviez un concept de fenêtre de connexion principale et des autres fenêtres que vous utilisiez. Dans votre fenêtre principale, vous aimeriez que les notifications soient envoyées à n'importe quel nouveau courrier, éventuellement en exécutant d’autres programmes en arrière-plan.

Pour supporter ceci, les shells ont trouvé un fichier .profile en particulier sur les "shells de connexion". Cela ferait le spécial, une fois une configuration de session. Bash a quelque peu élargi ce point pour regarder .bash_profile avant .profile, de cette façon vous ne pouvez mettre que des choses bash (donc ils ne bousillent pas le shell Bourne, etc., qui a également regardé .profile). Les autres shells, non-login, ne feraient que générer le fichier rc, .bashrc (ou .kshrc, etc.).

C'est un peu un anachronisme maintenant. Vous ne vous connectez pas à un shell principal autant que vous vous connectez à un gestionnaire de fenêtres. Il n'y a pas de fenêtre principale différente de toute autre fenêtre.

Ma suggestion - ne vous inquiétez pas de cette différence, elle est basée sur un ancien style d'utilisation d'Unix. Éliminez la différence dans vos fichiers. Le contenu entier de .bash_profile devrait être:

[ -f $HOME/.bashrc ] && . $HOME/.bashrc

Et mettez tout ce que vous voulez réellement mettre en .bashrc

Rappelez-vous que .bashrc provient de tous les shells, interactifs et non interactifs. Vous pouvez court-circuiter l'approvisionnement pour les shells non interactifs en plaçant ce code près du haut de .bashrc:

[[ $- != *i* ]] && return


34
2017-09-02 18:10



C'est une mauvaise idée, voir ma réponse. En particulier, vos variables d'environnement ne seront définies que dans les programmes lancés via le terminal, et non dans les programmes lancés directement avec une icône, un menu ou un raccourci clavier. - Gilles
@Gilles Je ne comprends pas pourquoi vous revendiquez cela. Avec .$HOME/.bashrc comme Rich l'a montré ci-dessus, les paramètres de .bashrc sera disponible dans les shells de connexion, et donc l'environnement de bureau. Par exemple, sur mon système Fedora, gnome-session est commencé comme -$SHELL -c gnome-session, alors .profile est lu. - Mikel
@PiotrDobrogost Oh, oui, il y a un autre problème avec la réponse de Rich. Comprenant .bashrc dans .profile ne fonctionne généralement pas, car .profile peut être exécuté par /bin/sh et pas bash (par exemple sur Ubuntu pour un login graphique par défaut), et ce shell peut ne pas être interactif (par exemple pour une connexion graphique). - Gilles
@Gilles re: "y compris .bashrc dans .profile" n'est pas du tout ce qui était recommandé (bien au contraire, en fait). Soit la réponse a été modifiée (cela ne semble pas être le cas), ou vos commentaires ne correspondent pas à ce qui est dit. - michael
En général, +1, mais je voudrais ajouter à la recommandation de "court-circuiter ... pour les shells non interactifs" ("en haut de .bashrc: [[ $- != *i* ]] && return") J'aime certains de mes .bashrc à exécuter même pour les shells non interactifs, en particulier pour définir ssh hostname {command}, de sorte que les commandes à distance soient exécutées correctement (même si le shell n'est pas interactif). Mais d'autres paramètres plus tard dans .bashrc devrait être ignoré. Je vérifie généralement pour TERM = stupide et / ou non défini, puis renflouer tôt. - michael


Regardez ça excellent article de blog par ShreevatsaR. Voici un extrait, mais allez sur le blog, il comprend une explication pour des termes tels que "login shell", un organigramme et un tableau similaire pour Zsh.

Pour Bash, ils fonctionnent comme suit. Lisez la colonne appropriée. Exécute A, puis B, puis C, etc. Le B1, B2, B3 signifie qu'il n'exécute que le premier de ces fichiers.

+----------------+-----------+-----------+------+
|                |Interactive|Interactive|Script|
|                |login      |non-login  |      |
+----------------+-----------+-----------+------+
|/etc/profile    |   A       |           |      |
+----------------+-----------+-----------+------+
|/etc/bash.bashrc|           |    A      |      |
+----------------+-----------+-----------+------+
|~/.bashrc       |           |    B      |      |
+----------------+-----------+-----------+------+
|~/.bash_profile |   B1      |           |      |
+----------------+-----------+-----------+------+
|~/.bash_login   |   B2      |           |      |
+----------------+-----------+-----------+------+
|~/.profile      |   B3      |           |      |
+----------------+-----------+-----------+------+
|BASH_ENV        |           |           |  A   |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|                |           |           |      |
+----------------+-----------+-----------+------+
|~/.bash_logout  |    C      |           |      |
+----------------+-----------+-----------+------+

14
2017-07-13 08:53



Plutôt que de poster la même réponse sur plusieurs questions, il est préférable que vous puissiez adapter votre réponse aux besoins spécifiques du demandeur. Si la réponse est exactement la même pour les deux questions, vous devriez poster une seule réponse et voter pour fermer les autres questions en double de l'original. - Mokubai♦
@Mokubai L'autre question a déjà été marquée en double. - Flimm
@ElipticalView: par jeu pour ne rien faire, vous faites référence à la ligne: [ -z "$PS1" ] && return? La table dans ma réponse donne la liste des scripts exécutés par Bash quel que soit le contenu des scripts, si le script lui-même a la ligne [ -z "$PS1" ] && return, bien sûr, cela prendrait effet, mais je ne pense pas que cela devrait signifier que je devrais changer de table. - Flimm


UN MEILLEUR COMMENTAIRE POUR LE CHEF DE / ETC / PROFIL

En me basant sur la bonne réponse de Flimm ci-dessus, j'ai inséré ce nouveau commentaire à la tête de mon profil Debian / etc /, (vous devrez peut-être l'ajuster pour votre distribution.):

# For BASH: Read down the appropriate column. Executes A, then B, then C, etc.
# The B1, B2, B3 means it executes only the first of those files found.  (A)
# or (B2) means it is normally sourced by (read by and included in) the
# primary file, in this case A or B2.
#
# +---------------------------------+-------+-----+------------+
# |                                 | Interactive | non-Inter. |
# +---------------------------------+-------+-----+------------+
# |                                 | login |    non-login     |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   ALL USERS:                    |       |     |            |
# +---------------------------------+-------+-----+------------+
# |BASH_ENV                         |       |     |     A      | not interactive or login
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile                     |   A   |     |            | set PATH & PS1, & call following:
# +---------------------------------+-------+-----+------------+
# |/etc/bash.bashrc                 |  (A)  |  A  |            | Better PS1 + command-not-found 
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/bash_completion.sh|  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |/etc/profile.d/vte-2.91.sh       |  (A)  |     |            | Virt. Terminal Emulator
# |/etc/profile.d/vte.sh            |  (A)  |     |            |
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# |   A SPECIFIC USER:              |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_profile    (bash only)   |   B1  |     |            | (doesn't currently exist) 
# +---------------------------------+-------+-----+------------+
# |~/.bash_login      (bash only)   |   B2  |     |            | (didn't exist) **
# +---------------------------------+-------+-----+------------+
# |~/.profile         (all shells)  |   B3  |     |            | (doesn't currently exist)
# +---------------------------------+-------+-----+------------+
# |~/.bashrc          (bash only)   |  (B2) |  B  |            | colorizes bash: su=red, other_users=green
# +---------------------------------+-------+-----+------------+
# |                                 |       |     |            |
# +---------------------------------+-------+-----+------------+
# |~/.bash_logout                   |    C  |     |            |
# +---------------------------------+-------+-----+------------+
#
# ** (sources !/.bashrc to colorize login, for when booting into non-gui)

Et cette note en tête de chacun des autres fichiers de configuration pour s'y référer:

# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE

Il est intéressant de noter que / etc / profile par défaut de Debian (includes) /etc/bash.bashrc (si /etc/bash.bashrc existe). Les scripts de connexion lisent donc les fichiers / etc, alors que les non-login ne lisent que bash.bashrc.

Il convient également de noter que /etc/bash.bashrc est configuré pour ne rien faire lorsqu'il n'est pas exécuté de manière interactive. Ces deux fichiers ne sont donc que des scripts interactifs.


3
2017-10-18 18:13