Cada vegada que obres un terminal o entres en un servidor per SSH, Bash llegeix uns quants fitxers de configuració abans de mostrar-te el prompt. En aquests fitxers és on es defineixen el PATH, les variables d’entorn, els àlies, les funcions i el mateix prompt. Saber quins fitxers es llegeixen, en quin ordre i en quin tipus de sessió és clau per entendre per què «l’àlies funciona en un terminal però no en l’altre» o per què una variable no té el valor que esperaves.
Nota sobre la versió original d’aquest article. L’ordre de fitxers que donava no era correcte: barrejava els fitxers de les sessions d’inici de sessió amb els de les altres, parlava d’un ~/.bash.bashrc que no existeix, i l’exemple pràctic no dona el mateix resultat a totes les distribucions. Aquí tens l’explicació corregida i comprovada a Debian 13 i a Rocky Linux 9.
Primer: quin tipus de shell tens?
Bash distingeix dues coses:
- Shell d’inici de sessió (login shell): el que s’obre quan inicies sessió. Per exemple, quan entres per SSH, quan inicies sessió en una consola de text, amb
su -o ambbash -l. - Shell interactiu que no és d’inici de sessió: el que obres des d’un shell que ja tens, escrivint
bash, o el que obren la majoria de terminals d’un escriptori gràfic.
A més, hi ha els shells no interactius: els que executen un script. Aquests no llegeixen cap dels fitxers d’aquest article.
Per saber en quin tipus de shell ets:
$ shopt login_shell
login_shell on
$ echo $0
-bash
Si login_shell surt on, o $0 comença per un guió (-bash), és un shell d’inici de sessió.
Quins fitxers llegeix Bash
| Tipus de shell | Fitxers del sistema | Fitxers de l’usuari |
|---|---|---|
| D’inici de sessió | /etc/profile | el primer que existeixi de ~/.bash_profile, ~/.bash_login i ~/.profile |
| Interactiu, no d’inici de sessió | /etc/bash.bashrc (Debian i Ubuntu) | ~/.bashrc |
| En tancar un shell d’inici de sessió | ~/.bash_logout | |
| No interactiu (scripts) | cap | cap (només el fitxer que indiqui la variable BASH_ENV, si n’hi ha) |
Dos detalls importants:
- En un shell d’inici de sessió, Bash no llegeix
~/.bashrcpel seu compte. Si es llegeix, és perquè~/.profileo~/.bash_profileel criden explícitament (i a les distribucions habituals ho fan). - Dels tres fitxers personals d’inici de sessió, Bash només en llegeix un. Si a Debian o Ubuntu crees un
~/.bash_profile, el~/.profileque ja tenies deixa de llegir-se.
Com ho encadenen les distribucions
Els fitxers es criden els uns als altres, i cada família de distribucions ho fa a la seva manera.
Debian i Ubuntu
/etc/profiledefineix elPATH, crida/etc/bash.bashrc(si el shell és Bash i interactiu) i, després, els scripts de/etc/profile.d/*.sh./etc/bash.bashrcés la configuració comuna dels shells interactius: el prompt per defecte, l’autocompletat, etc. El Bash de Debian el llegeix directament en els shells que no són d’inici de sessió.~/.profile(creat a partir de/etc/skel/.profile) crida~/.bashrci afegeix~/bini~/.local/binalPATHsi existeixen.~/.bashrcconté els àlies, l’historial i el prompt de l’usuari.
Rocky, Alma, RHEL i Fedora
/etc/profiledefineix l’entorn i crida els scripts de/etc/profile.d/*.sh.- El fitxer global dels shells interactius es diu
/etc/bashrc(no/etc/bash.bashrc), i Bash no el llegeix pel seu compte: el crida~/.bashrc. ~/.bash_profilecrida~/.bashrc.
Pots veure la cadena a la teva màquina amb aquests grep:
$ grep -n bashrc /etc/profile ~/.profile ~/.bash_profile 2>/dev/null
Exemple pràctic
Suposem que, com a root, afegim una línia al final de cadascun d’aquests fitxers:
- A
/etc/profile:
GLOBAL_PROFILE=prova11
- Al fitxer global dels shells interactius (
/etc/bash.bashrca Debian,/etc/bashrca Rocky):
GLOBAL_PROFILE=prova22
Shell que no és d’inici de sessió (bash): només es llegeix el fitxer global dels shells interactius, de manera que la variable val prova22 a totes dues distribucions.
$ bash
$ echo $GLOBAL_PROFILE
prova22
Shell d’inici de sessió (bash -l): aquí el resultat depèn de la distribució, perquè depèn de l’ordre en què s’executen les línies:
- Debian i Ubuntu:
/etc/profilecrida/etc/bash.bashrccap al principi (la variable passa a valerprova22) i, en arribar a la seva última línia, la torna a canviar. Resultat:prova11. - Rocky, Alma i Fedora: primer s’executa sencer
/etc/profile(prova11) i després~/.bash_profilecrida~/.bashrc, que crida/etc/bashrc. Resultat:prova22.
$ bash -l
$ echo $GLOBAL_PROFILE
prova11 ← Debian i Ubuntu
prova22 ← Rocky, Alma i Fedora
La lliçó és que l’ordre real no és una llista fixa: és el resultat de quins fitxers es criden entre ells i en quin punt. Si una variable no té el valor que esperes, busca on es defineix (grep -n NOM_VARIABLE /etc/profile /etc/profile.d/* /etc/bash.bashrc ~/.profile ~/.bashrc) i segueix la cadena.
Fixa’t també que en aquest exemple la variable no porta export: només existeix en el shell que l’ha definida, no en els programes que s’hi executen. Per a una variable d’entorn de debò, escriu export GLOBAL_PROFILE=prova11.
Comprova-ho tu mateix sense tocar res
Pots veure l’ordre de lectura dels fitxers personals amb un directori personal de prova, sense modificar els teus fitxers reals:
mkdir /tmp/prova
cd /tmp/prova
for f in .bash_profile .bash_login .profile .bashrc .bash_logout; do
echo "echo llegint $f" > "$f"
done
Ara obre shells de cada tipus amb HOME=/tmp/prova:
$ HOME=/tmp/prova bash -l -c true
llegint .bash_profile
$ HOME=/tmp/prova bash -i -c true
llegint .bashrc
$ HOME=/tmp/prova bash -c true
$
El shell d’inici de sessió només ha llegit ~/.bash_profile (el primer de la llista), l’interactiu només ~/.bashrc i el no interactiu, cap. Si esborres .bash_profile, el shell d’inici de sessió llegirà .bash_login, i si esborres aquest, .profile. Quan acabis, esborra el directori de prova amb rm -r /tmp/prova.
On posar cada cosa
| Vols configurar… | Fitxer |
|---|---|
| Àlies, funcions, prompt, opcions de l’historial (per a tu) | ~/.bashrc |
Variables d’entorn i PATH (per a tu) | ~/.profile (Debian/Ubuntu) o ~/.bash_profile (Rocky/Fedora) |
| Variables d’entorn per a tots els usuaris | un fitxer nou a /etc/profile.d/, per exemple /etc/profile.d/empresa.sh |
| Àlies o prompt per a tots els usuaris | /etc/bash.bashrc (Debian/Ubuntu) o /etc/bashrc (Rocky/Fedora) |
| Accions en tancar la sessió | ~/.bash_logout |
Els fitxers de /etc els pot sobreescriure una actualització del paquet; per això és millor afegir un fitxer propi a /etc/profile.d/ que no pas editar /etc/profile.
Si fas el teu propi ~/.bash_profile, posa-hi això perquè els shells d’inici de sessió també llegeixin ~/.bashrc:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
Per aplicar els canvis de ~/.bashrc al terminal on ets, sense obrir-ne un de nou:
source ~/.bashrc
Els canvis de ~/.profile o /etc/profile s’apliquen en el proper inici de sessió.
Conclusió
Bash no llegeix tots els fitxers de configuració sempre: depèn de si el shell és d’inici de sessió, interactiu o un script, i de com la teva distribució encadena els fitxers. Amb la taula d’aquest article i una mica de grep pots saber exactament d’on surt cada àlies i cada variable, i posar cada configuració al lloc que toca.
Referències
- Bash Reference Manual: Bash Startup Files
- La pàgina del manual:
man bash, apartat INVOCATION. - Linux Command Line and Shell Scripting Bible, de Richard Blum i Christine Bresnahan (Wiley).