Shell Scripting

Els fitxers d’inici de Bash: /etc/profile, .bashrc i .bash_profile



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 amb bash -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 shellFitxers del sistemaFitxers de l’usuari
D’inici de sessió/etc/profileel 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)capcap (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 ~/.bashrc pel seu compte. Si es llegeix, és perquè ~/.profile o ~/.bash_profile el 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 ~/.profile que 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/profile defineix el PATH, 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 ~/.bashrc i afegeix ~/bin i ~/.local/bin al PATH si existeixen.
  • ~/.bashrc conté els àlies, l’historial i el prompt de l’usuari.

Rocky, Alma, RHEL i Fedora

  • /etc/profile defineix 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_profile crida ~/.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.bashrc a Debian, /etc/bashrc a 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/profile crida /etc/bash.bashrc cap al principi (la variable passa a valer prova22) 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_profile crida ~/.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 usuarisun 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

Posts relacionats