Différence entre .bashrc et .bash_profile
Quelle est la différence entre .bashrcet .bash_profileet lequel dois-je utiliser?
Réponses
Traditionnellement, lorsque vous vous connectez à un système Unix, le système démarre un programme pour vous. Ce programme est un shell, c'est-à-dire un programme conçu pour démarrer 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 Bourne shell, lit les commandes à partir du ~/.profilemoment où il est appelé comme shell de connexion.
Bash est un shell de type Bourne. Il lit les commandes à partir du ~/.bash_profilemoment où il est appelé comme shell de connexion, et si ce fichier n'existe pas¹, il essaie de lire à la ~/.profileplace.
Vous pouvez appeler 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 démarrez bash en tant que shell interactif (c'est-à-dire pour ne pas exécuter de script), il lit ~/.bashrc(sauf lorsqu'il est appelé comme shell de connexion, alors il lit uniquement ~/.bash_profileou ~/.profile.
Par conséquent:
~/.profileest l'endroit où placer les é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 vont dans un fichier différent) et les définitions de variables d'environnement.~/.bashrcest 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 du shell et les paramètres d'invite. (Vous pouvez également y mettre des raccourcis clavier, mais pour bash, ils vont normalement dans~/.inputrc.)~/.bash_profilepeut être utilisé à la place de~/.profile, mais il est lu uniquement par bash, pas par un autre shell. (Ceci est principalement un problème si vous voulez que vos fichiers d'initialisation fonctionnent sur plusieurs machines et que votre shell de connexion ne les bash pas tous.) C'est un endroit logique à inclure~/.bashrcsi 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 unités modernes, il y a une complication supplémentaire liée à ~/.profile. Si vous vous connectez dans un environnement graphique (qui est, si le programme où vous tapez votre mot de passe est en cours d' exécution en mode graphique), vous ne recevez 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 façon dont votre distribution a configuré ces programmes, votre ~/.profilepeut ou non être lu. Si ce n'est pas le cas, il existe 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 insérer des définitions de variables d'environnement ~/.bashrcou 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 démarrés directement avec une icône, un menu ou un raccourci clavier.
¹ Par souci d' exhaustivité, sur demande: s'il .bash_profilen'existe pas, bash essaie également .bash_loginavant de revenir à .profile. N'hésitez pas à oublier qu'il existe.
De ce court article
Selon la page de manuel 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 à la machine lors du démarrage, soit à distance via ssh: .bash_profile est exécuté pour configurer les choses avant l'invite de commande initiale.
Mais, si vous vous êtes déjà connecté à votre machine et 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 bash en tapant / bin / bash dans un terminal.
Dans l'ancien temps, quand les pseudo tty n'étaient pas pseudo et en fait, eh bien, tapés, et les UNIX étaient accessibles par des modems si lents que vous pouviez voir chaque lettre imprimée sur votre écran, l'efficacité était primordiale. Pour améliorer quelque peu l'efficacité, vous aviez un concept de fenêtre de connexion principale et de toutes les autres fenêtres que vous utilisiez réellement. Dans votre fenêtre principale, vous souhaitez recevoir des notifications pour tout nouveau courrier, éventuellement exécuter d'autres programmes en arrière-plan.
Pour supporter cela, les shells ont extrait un fichier .profilespécifiquement sur les «shells de connexion». Cela ferait le spécial, une fois la configuration de la session. Bash a quelque peu étendu cela pour regarder .bash_profile d'abord avant .profile, de cette façon vous pourriez mettre bash seulement des choses là-dedans (afin qu'ils ne foutent pas le Bourne shell, etc., qui regardait également .profile). D'autres shells, sans connexion, 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 d'interface graphique. 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 style plus ancien d'utilisation d'Unix. Éliminez la différence dans vos fichiers. Le contenu entier de .bash_profile doit être:
[ -f $HOME/.bashrc ] && . $HOME/.bashrc
Et mettez tout ce que vous voulez réellement définir dans .bashrc
N'oubliez pas que .bashrc provient de tous les shells, interactifs et non interactifs. Vous pouvez court-circuiter le sourcing pour les shells non interactifs en plaçant ce code en haut de .bashrc:
[[ $- != *i* ]] && return
Jetez un œil à cet excellent article de blog de ShreevatsaR . Voici un extrait, mais allez sur le billet de blog, il comprend une explication pour des termes comme "shell de connexion", 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 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 | | |
+----------------+-----------+-----------+------+
UN MEILLEUR COMMENTAIRE POUR LE CHEF DE / ETC / PROFILE
En me basant sur la bonne réponse de Flimm ci-dessus, j'ai inséré ce nouveau commentaire en tête de ma Debian /etc/profile, (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 d'installation pour s'y référer:
# TIP: SEE TABLE in /etc/profile of BASH SETUP FILES AND THEIR LOAD SEQUENCE
Il convient de noter que je pense que les /etc/profilesources par défaut de Debian (incluent) /etc/bash.bashrc, (c'est quand elles /etc/bash.bashrcexistent). Ainsi, les scripts de connexion lisent les deux /etcfichiers, tandis que les non-login ne lisent que bash.bashrc.
Il convient également de noter qu'il /etc/bash.bashrcest configuré pour ne rien faire lorsqu'il n'est pas exécuté de manière interactive. Ces deux fichiers sont donc uniquement destinés aux scripts interactifs.
La logique de configuration de bash's elle-même n'est pas complètement compliquée et expliquée dans d'autres réponses de cette page, sur serverfault et dans de nombreux blogs. Le problème, cependant, c'est ce que les distributions Linux font de bash , je veux dire la complexité et les diverses façons dont elles configurent bash par défaut.http://mywiki.wooledge.org/DotFilesmentionne brièvement certaines de ces bizarreries. Voici un exemple de trace sur Fedora 29, il montre quels fichiers source 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-shell:
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 vu ci /etc/bashrc- dessus, c'est un fichier que bash lui-même ne connaît pas, je veux dire pas directement. Fedora /etc/bashrcteste si:
- il provient d'un shell de connexion,
- il provient d'un shell interactif,
- il a déjà été sourcé
... puis fait des choses complètement différentes en fonction de ceux-ci.
Si vous pensez que vous pouvez vous souvenir du graphique ci-dessus, tant pis car ce n'est pas assez: 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 des bash_completionscripts. Pour des raisons de compatibilité descendante, invoquer bash as /bin/shau lieu de /bin/bashmodifier son comportement. Qu'en est-il de zsh et d'autres shells? Et bien sûr, différentes distributions Linux font les choses différemment, par exemple Debian et Ubuntu sont livrées avec une version non standard de bas h, elle a des personnalisations spécifiques à Debian. Il semble notamment pour un fichier hors du commun: /etc/bash.bashrc. Même si vous vous en tenez à une seule distribution Linux, elle évolue probablement avec le temps. Attendez: nous n'avons même pas touché macOS, FreeBSD, ... Enfin, réfléchissons aux utilisateurs bloqués par les façons encore plus créatives dont leurs administrateurs ont configuré le système qu'ils doivent utiliser.
Comme le montre le flux interminable de discussions sur ce sujet, c'est une cause perdue. Tant que vous souhaitez simplement ajouter de nouvelles valeurs, certains «essais et erreurs» ont tendance à être suffisants. Le vrai plaisir commence lorsque vous voulez modifier dans un fichier (utilisateur) quelque chose de déjà défini dans un autre (dans / etc). Préparez-vous ensuite à passer du temps à concevoir une solution qui ne sera jamais portable.
Pour un dernier moment de plaisir, voici le "graphique 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