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

Verschil tussen .bashrc en .bash_profile

Wat is het verschil tussen .bashrc en .bash_profile en welke moet ik gebruiken?

Antwoorden (6)

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

Traditioneel, wanneer je inlogt op een Unix systeem, start het systeem één programma voor je. Dat programma is een shell, d.w.z. een programma dat is ontworpen om andere programma’s te starten. Het is een commandoregel-shell: je start een ander programma door de naam ervan te typen. De standaard shell, een Bourne shell, leest commando’s van ~/.profile wanneer deze wordt aangeroepen als de login shell.

Bash is een Bourne-achtige shell. Hij leest commando’s van ~/.bash_profile wanneer hij wordt aangeroepen als login-shell, en als dat bestand niet bestaat¹, probeert hij in plaats daarvan ~/.profile te lezen.

Je kunt een shell altijd direct aanroepen, bijvoorbeeld door een terminal emulator binnen een GUI omgeving te starten. Als de shell geen login-shell is, leest hij geen ~/.profile. Als je bash start als een interactieve shell (dus niet om een script te draaien), leest hij ~/.bashrc (behalve als hij wordt aangeroepen als een login-shell, dan leest hij alleen ~/.bash_profile of ~/.profile.

  • ~/.profile is dus de plaats om dingen in te zetten die voor je hele sessie gelden, zoals programma’s die je wilt starten als je inlogt (maar geen grafische programma’s, die gaan in een ander bestand), en omgevingsvariabelen definities.

  • ~/.bashrc is de plaats voor dingen die alleen voor bash zelf gelden, zoals alias- en functiedefinities, shell-opties, en prompt-instellingen. (Je zou hier ook toetscombinaties kunnen zetten, maar voor bash gaan die normaal gesproken in ~/.inputrc).

  • ~/.bash_profile kan gebruikt worden in plaats van ~/.profile, maar het wordt alleen gelezen door bash, niet door een andere shell. (Dit is vooral een probleem als u wilt dat uw initialisatiebestanden op meerdere machines werken en uw login-shell niet op alle machines bash is). Dit is een logische plaats om ~/.bashrc op te nemen als de shell interactief is. Ik raad de volgende inhoud in ~/.bash_profile aan:

Op moderne unices, is er een extra complicatie gerelateerd aan ~/.profile. Als je inlogt in een grafische omgeving (dat wil zeggen, als het programma waar je je wachtwoord intypt in grafische modus draait), krijg je niet automatisch een login-shell die ~/.profile leest. Afhankelijk van het grafische aanmeldprogramma, van de window manager of desktop omgeving die je daarna draait, en van hoe je distributie deze programma’s heeft geconfigureerd, kan je ~/.profile wel of niet gelezen worden. Als dat niet het geval is, is er meestal een andere plaats waar je omgevingsvariabelen kunt definiëren en programma’s kunt starten als je inlogt, maar er is helaas geen standaard plaats.

Merk op dat u hier en daar aanbevelingen ziet om ofwel omgevingsvariabeldefinities in ~/.bashrc te zetten ofwel login-shells altijd in terminals te starten. Beide zijn slechte ideeën. Het meest voorkomende probleem met een van deze ideeën is dat uw omgevingsvariabelen alleen ingesteld worden in programma’s die via de terminal gestart worden, niet in programma’s die direct gestart worden met een icoon of menu of sneltoetscombinatie.

¹ Voor de volledigheid, op verzoek: als .bash_profile niet bestaat, probeert bash ook .bash_login alvorens terug te vallen op .profile. Voel je vrij om te vergeten dat het bestaat.

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

Uit dit korte artikel

Volgens de bash man page, wordt .bash_profile uitgevoerd voor login shells, terwijl .bashrc wordt uitgevoerd voor interactieve niet-login shells.

Wat is een login of niet-login shell?

Wanneer je inlogt (b.v.: gebruikersnaam en wachtwoord intypt) via console, hetzij fysiek zittend op de machine bij het booten, of op afstand via ssh: .bash_profile wordt uitgevoerd om dingen te configureren voor de initiële command prompt.

Maar, als je al ingelogd bent op je machine en een nieuw terminal venster (xterm) opent in Gnome of KDE, dan wordt .bashrc uitgevoerd voor de window command prompt. .bashrc wordt ook uitgevoerd als je een nieuwe bash instantie start door /bin/bash in een terminal te typen.

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

Vroeger, toen pseudo tty’s nog geen pseudo waren en echt, nou ja, getypt werden, en UNIXen benaderd werden door modems die zo traag waren dat je elke letter kon zien die op je scherm werd afgedrukt, was efficiëntie van het grootste belang. Om de efficiëntie enigszins te bevorderen had je een concept van een hoofd login venster en de andere vensters die je gebruikte om echt te werken. In je hoofdvenster wilde je meldingen hebben over nieuwe mail, eventueel wat andere programma’s op de achtergrond laten draaien.

Om dit te ondersteunen, maakten shells gebruik van een bestand .profile specifiek voor ‘login shells’. Dit zou het speciale doen, zodra een sessie was opgezet. Bash breidde dit enigszins uit door eerst naar .bash_profile te kijken en dan pas naar .profile, op deze manier kon je er alleen bash dingen in zetten (zodat ze niet Bourne shell, etc, verpesten, die ook naar .profile keken). Andere shells, niet-login, zouden gewoon het rc bestand, .bashrc (of .kshrc, etc).

Dit is nu een beetje een anachronisme. Je logt niet zozeer in op een hoofd-shell als wel op een gui window manager. Er is geen hoofdvenster dat anders is dan ieder ander venster.

Mijn suggestie - maak je geen zorgen over dit verschil, het is gebaseerd op een oudere manier van Unix gebruiken. Elimineer het verschil in je bestanden. De volledige inhoud van .bash_profile zou moeten zijn:

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

En zet alles wat je eigenlijk wilt instellen in .bashrc

Onthoud dat .bashrc wordt gesourced voor alle shells, interactief en niet-interactief. Je kunt de sourcing voor niet-interactieve shells kortsluiten door deze code bovenaan .bashrc te zetten:

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

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

Kijk eens naar deze uitstekende blog post van ShreevatsaR . Hier is een uittreksel, maar ga naar de blog post, het bevat een uitleg voor termen als “login shell”, een stroomdiagram, en een vergelijkbare tabel voor Zsh.

Voor Bash werken ze als volgt. Lees de juiste kolom naar beneden. Voert A uit, dan B, dan C, enz. De B1, B2, B3 betekent dat alleen het eerste van die gevonden bestanden wordt uitgevoerd.

+----------------+-----------+-----------+------+
| |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

**Voortbordurend op Flimm’s geweldige antwoord hierboven, heb ik deze nieuwe opmerking aan het hoofd van mijn Debian /etc/profile gezet, (je moet het misschien aanpassen voor jouw 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)

En deze opmerking aan het hoofd van elk van de andere setup bestanden om er naar te verwijzen:

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

Het vermelden waard is denk ik dat Debian’s /etc/profile standaard bronnen (includes) /etc/bash.bashrc (dat is als /etc/bash.bashrc bestaat). Dus login scripts lezen beide /etc bestanden, terwijl niet-login alleen bash.bashrc leest.

Merk ook op dat /etc/bash.bashrc is ingesteld om niets te doen als het niet interactief wordt uitgevoerd. Dus deze twee bestanden zijn alleen voor interactieve scripts.

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

De configuratie logica van bash zelf is niet gek ingewikkeld en uitgelegd in andere antwoorden op deze pagina, op serverfault en in vele blogs. Het probleem is echter wat de Linux distributies van bash maken, ik bedoel de complexe en diverse manieren waarop ze bash standaard configureren. http://mywiki.wooledge.org/DotFiles vermeldt kort enkele van deze eigenaardigheden. Hier is een voorbeeld trace op Fedora 29, het laat zien welke bestanden welk ander bestand(en) source(s) en in welke volgorde voor een heel simpel scenario: op afstand verbinden met ssh en dan een andere subshell starten:

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

Fedora’s meest complexe logica zit in /etc/bashrc. Zoals hierboven gezien is /etc/bashrc een bestand waar bash zelf geen weet van heeft, ik bedoel niet direct. Fedora’s /etc/bashrc test of:

  • het wordt opgehaald door een login shell,
  • het wordt opgehaald door een interactieve shell,
  • het al is opgehaald

… en doet dan compleet verschillende dingen, afhankelijk van die.

Als je denkt dat je de bovenstaande grafiek kunt onthouden, jammer dan, want dat is lang niet genoeg: deze grafiek beschrijft slechts één scenario, er gebeuren iets andere dingen als je niet-interactieve scripts draait of een grafische sessie start. Ik heb ~/.profile weggelaten. Ik heb bash_completion scripts weggelaten. Omwille van achterwaartse compatibiliteit verandert het aanroepen van bash als /bin/sh in plaats van /bin/bash het gedrag. Hoe zit het met zsh en andere shells? En natuurlijk doen verschillende Linux distributies dingen anders, bijvoorbeeld Debian en Ubuntu komen met een niet-standaard versie van bash, het heeft Debian-specifieke aanpassingen (en). Het zoekt met name naar een ongebruikelijk bestand: /etc/bash.bashrc. Zelfs als je bij één enkele Linux distributie blijft, evolueert deze waarschijnlijk met de tijd. Wacht: we hebben het nog niet gehad over macOS, FreeBSD,… Tenslotte nog een gedachte voor gebruikers die vastzitten aan de nog creatievere manieren waarop hun admins het systeem hebben geconfigureerd dat ze moeten gebruiken.

Zoals de eindeloze stroom van discussies over dit onderwerp aantoont, is het een verloren zaak. Zolang je alleen maar nieuwe waarden wilt toevoegen, is wat “trial and error” meestal voldoende. De echte lol begint als je iets wilt wijzigen in een (gebruikers)bestand dat al in een ander (in /etc) is gedefinieerd. Wees er dan op voorbereid om wat tijd te besteden aan het ontwikkelen van een oplossing die nooit portable zal zijn.

Voor een laatste beetje plezier is hier de “source graph” voor hetzelfde, eenvoudige scenario op Clear Linux vanaf juni 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