2010-09-02 14:40:34 +0000 2010-09-02 14:40:34 +0000
453
453

Différence entre .bashrc et .bash_profile

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

Réponses (6)

528
528
528
2010-09-02 19:23:14 +0000

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 en 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 lorsqu'il est invoqué comme shell de connexion.

Bash est un shell de type Bourne. Il lit les commandes de ~/.bash_profile lorsqu'il est invoqué comme shell de connexion, et si ce fichier n'existe pas¹, il essaie de lire ~/.profile à la place.

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

Par conséquent :

  • ~/.profile est l'endroit où mettre les choses qui s'appliquent à toute votre session, comme les programmes que vous voulez lancer lorsque vous vous connectez (mais pas les programmes graphiques, ils vont dans un fichier différent), et les définitions des variables d'environnement.

  • ~/.bashrc est l'endroit pour mettre des choses qui ne s'appliquent qu'à bash lui-même, comme les définitions d'alias et de fonctions, les options du shell et les paramètres d'invite. (Vous pouvez aussi y mettre des raccourcis clavier, mais pour bash ils vont normalement dans ~/.inputrc.)

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

Sur les unités 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 où vous tapez votre mot de passe fonctionne en mode graphique), vous n'obtenez pas automatiquement un shell de connexion qui lit ~/.profile. Selon le programme de connexion graphique, le gestionnaire de fenêtres ou l'environnement de bureau que vous exécutez ensuite, et la façon dont votre distribution a configuré ces programmes, votre ~/.profile peut ou non être lu. Si ce n'est pas le cas, il y a généralement un autre endroit où vous pouvez définir les variables d'environnement et les programmes à lancer lorsque vous vous connectez, mais il n'y a malheureusement pas d'emplacement standard.

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. 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 ou un menu ou un raccourci clavier.

¹ Pour être complet, par demande : si .bash_profile n'existe pas, bash essaie aussi .bash_login avant de revenir à .profile. N'hésitez pas à oublier qu'il existe.

54
54
54
2010-09-02 14:54:04 +0000

D'après la page de manuel de bash, .bash_profile est exécuté pour les shells de connexion, tandis que .bashrc est exécuté pour les shells interactifs sans connexion.

**Qu'est-ce qu'un shell avec ou sans connexion ?

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

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

35
35
35
2010-09-02 18:10:20 +0000

Dans le temps, quand les pseudo tty n'étaient pas des pseudo tty et qu'ils étaient en fait tapés à la machine, et que l'accès aux UNIX se faisait par des modems si lents que vous pouviez voir chaque lettre s'imprimer sur votre écran, l'efficacité était primordiale. Pour améliorer un peu l'efficacité, vous aviez le concept d'une fenêtre de connexion principale et de toutes les autres fenêtres que vous utilisiez pour travailler. Dans votre fenêtre principale, vous souhaitez être averti de tout nouveau courrier, et éventuellement exécuter d'autres programmes en arrière-plan.

Pour cela, les shells ont créé un fichier .profile spécifiquement sur les “shells de connexion”. Cela permet de faire le spécial, une fois la session configurée. Bash a quelque peu étendu ce système pour regarder d'abord .bash_profile avant .profile, de cette façon vous pouvez mettre des choses de bash seulement là-dedans (pour qu'ils ne bousillent pas le shell Bourne, etc, qui regardait aussi .profile). D'autres shells, sans connexion, se contenteraient de fournir le fichier rc, .bashrc (ou .kshrc, etc.).

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

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. Tout le contenu de .bash_profile devrait l'être :

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

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

Rappelez-vous que .bashrc est fourni pour tous les shells, interactifs et non interactifs. Vous pouvez court-circuiter le sourcing des shells non interactifs en mettant ce code en haut du .bashrc :

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

19
19
19
2016-07-13 08:53:44 +0000

Jetez un coup d'œil à cet excellent article de blog par ShreevatsaR . En voici un extrait, mais allez voir l'article du blog, il comprend une explication de termes comme “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. Les B1, B2, B3 signifient qu'il n'exécute que le premier des fichiers trouvés.

+----------------+-----------+-----------+------+
| |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 | | |
+----------------+-----------+-----------+------+
5
5
5
2016-10-18 18:13:24 +0000

Un meilleur commentaire pour la tête du fichier /etc/profile

En me basant sur l'excellente réponse de Flimm ci-dessus, j'ai inséré ce nouveau commentaire en tête de mon fichier /etc/profile Debian, (vous pourriez avoir besoin de l'ajuster pour votre distro.) :

# 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 d'installation pour y faire référence :

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

Il faut noter, je pense, que le fichier /etc/profile par défaut des sources de Debian (inclut) /etc/bash.bashrc (c'est quand /etc/bash.bashrc existe). Donc les scripts de connexion lisent les deux fichiers /etc, alors que les scripts de non-login ne lisent que bash.bashrc.

Il faut également 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 destinés qu'à des scripts interactifs.

4
4
4
2019-06-24 22:55:40 +0000

La logique de configuration de bash’s elle-même n'est pas follement compliquée et est expliquée dans d'autres réponses sur cette page, sur le défaut du serveur et dans de nombreux blogs. Le problème cependant est ce que les distributions Linux font de bash, je veux dire la complexité et les différentes façons dont elles configurent bash par défaut. http://mywiki.wooledge.org/DotFiles mentionne brièvement certaines de ces bizarreries. Voici un exemple de trace sur Fedora 29, il montre quels fichiers sont à l'origine de quel(s) autre(s) fichier(s) et dans quel ordre pour un scénario très simple : se connecter à distance avec ssh puis démarrer un autre sous-système :

ssh fedora29
 └─ -bash # login shell
      ├── /etc/profile
      | ├─ /etc/profile.d/*.sh
      | ├─ /etc/profile.d/sh.local
      | └─ /etc/bashrc
      ├── ~/.bash_profile
      | └─ ~/.bashrc
      | └─ /etc/bashrc
      |
      |
      └─ $ bash # non-login shell
            └─ ~/.bashrc
                 └─ /etc/bashrc
                       └─ /etc/profile.d/*.sh

La logique la plus complexe de Fedora est dans /etc/bashrc. Comme nous l'avons vu plus haut, /etc/bashrc est un fichier dont la base de données elle-même n'est pas au courant, je veux dire pas directement. Le /etc/bashrc de Fedora teste si :

  • il est généré par un shell de connexion,
  • il est généré par un shell interactif,
  • il a déjà été généré

… et fait ensuite des choses complètement différentes en fonction de cela.

Si vous pensez pouvoir vous souvenir du graphique ci-dessus, alors tant pis car il est loin d'être suffisant : ce graphique ne décrit qu'un seul scénario, des choses légèrement différentes se produisent lors de l'exécution de scripts non interactifs ou du démarrage d'une session graphique. J'ai omis ~/.profile. J'ai omis les scripts bash_completion. Pour des raisons de rétrocompatibilité, invoquer bash comme /bin/sh au lieu de /bin/bash modifie son comportement. Qu'en est-il de zsh et des autres shells ? Et bien sûr, les différentes distributions de Linux font les choses différemment, par exemple Debian et Ubuntu sont livrés avec une version non standard de bash, elle a une ou plusieurs personnalisations spécifiques à Debian. Il recherche notamment un fichier inhabituel : /etc/bash.bashrc. Même si vous vous en tenez à une seule distribution Linux, elle évolue probablement au fil du temps. Attendez : nous n'avons même pas touché à macOS, FreeBSD,… Enfin, ayons une pensée pour les utilisateurs coincés avec les façons encore plus créatives dont leurs administrateurs ont configuré le système qu'ils doivent utiliser.

Comme le montre le flux incessant de discussions sur ce sujet, c'est une cause perdue. Tant que vous voulez juste ajouter de nouvelles valeurs, quelques “essais et erreurs” tendent à suffire. Le vrai plaisir commence lorsque vous voulez modifier dans un fichier (utilisateur) quelque chose qui est déjà défini dans un autre (dans /etc). Soyez alors prêt à passer un peu de temps à concevoir une solution qui ne sera jamais portable.

Pour un dernier plaisir, voici le “graphe source” du même scénario simple sur Clear Linux à partir de juin 2019 :

ssh clearlinux
 └─ -bash # login shell
      ├── /usr/share/defaults/etc/profile
      | ├─ /usr/share/defaults/etc/profile.d/*
      | ├─ /etc/profile.d/*
      | └─ /etc/profile
      ├── ~/.bash_profile
      |
      |
      └─ $ bash # non-login shell
           ├─ /usr/share/defaults/etc/bash.bashrc
           | ├─ /usr/share/defaults/etc/profile
           | | ├─ /usr/share/defaults/etc/profile.d/*
           | | ├─ /etc/profile.d/*
           | | └─ /etc/profile
           | └─ /etc/profile
           └─ ~/.bashrc
```.