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

Unterschied zwischen .bashrc und .bash_profile

Was ist der Unterschied zwischen .bashrc und .bash_profile und welches sollte ich verwenden?

Antworten (6)

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

Wenn Sie sich bei einem Unix-System anmelden, startet das System traditionell ein Programm für Sie. Dieses Programm ist eine Shell, d. h. ein Programm zum Starten anderer Programme. Es ist eine Kommandozeilen-Shell: Sie starten ein anderes Programm, indem Sie dessen Namen eingeben. Die Standardshell, eine Bourne-Shell, liest Befehle von ~/.profile, wenn sie als Anmeldeshell aufgerufen wird.

Die Bash ist eine Bourne-ähnliche Shell. Sie liest Befehle aus ~/.bash_profile, wenn sie als Login-Shell aufgerufen wird, und wenn diese Datei nicht existiert¹, versucht sie stattdessen ~/.profile zu lesen.

Sie können eine Shell jederzeit direkt aufrufen, z. B. durch Starten eines Terminalemulators innerhalb einer GUI-Umgebung. Wenn die Shell keine Login-Shell ist, liest sie nicht ~/.profile. Wenn Sie die Bash als interaktive Shell starten (also nicht, um ein Skript auszuführen), liest sie ~/.bashrc (außer wenn sie als Login-Shell aufgerufen wird, dann liest sie nur ~/.bash_profile oder ~/.profile.

Daher:

  • ~/.profile ist der Ort, an dem Dinge abgelegt werden, die für Ihre gesamte Sitzung gelten, wie Programme, die Sie beim Einloggen starten wollen (aber keine grafischen Programme, die kommen in eine andere Datei), und Definitionen von Umgebungsvariablen.

  • ~/.bashrc ist der Ort, an dem Dinge abgelegt werden, die nur für die Bash selbst gelten, wie Alias- und Funktionsdefinitionen, Shell-Optionen und Prompt-Einstellungen. (Sie könnten dort auch Tastaturbelegungen ablegen, aber für die Bash gehören sie normalerweise in ~/.inputrc.)

  • ~/.bash_profile kann anstelle von ~/.profile verwendet werden, aber es wird nur von der Bash gelesen, nicht von einer anderen Shell. (Das ist vor allem dann ein Problem, wenn Sie wollen, dass Ihre Initialisierungsdateien auf mehreren Rechnern funktionieren und Ihre Login-Shell nicht auf allen die Bash ist.) Dies ist ein logischer Ort, um ~/.bashrc einzuschließen, wenn die Shell interaktiv ist. Ich empfehle den folgenden Inhalt in ~/.bash_profile:

Auf modernen Unis gibt es eine zusätzliche Komplikation im Zusammenhang mit ~/.profile. Wenn Sie sich in einer grafischen Umgebung anmelden (d. h., wenn das Programm, in das Sie Ihr Kennwort eingeben, im Grafikmodus läuft), erhalten Sie nicht automatisch eine Anmeldeshell, die ~/.profile liest. Je nach dem grafischen Anmeldeprogramm, dem Fenstermanager oder der Desktop-Umgebung, die Sie danach ausführen, und je nachdem, wie Ihre Distribution diese Programme konfiguriert hat, kann Ihr ~/.profile gelesen werden oder auch nicht. Wenn das nicht der Fall ist, gibt es normalerweise einen anderen Ort, an dem Sie Umgebungsvariablen und Programme definieren können, die beim Anmelden gestartet werden sollen, aber es gibt leider keinen Standardort.

Beachten Sie, dass Sie hier und da Empfehlungen sehen, entweder Umgebungsvariablendefinitionen in ~/.bashrc abzulegen oder Anmeldeshells immer in Terminals zu starten. Beides sind schlechte Ideen. Das häufigste Problem bei beiden Ideen ist, dass Ihre Umgebungsvariablen nur in Programmen gesetzt werden, die über das Terminal gestartet werden, nicht aber in Programmen, die direkt über ein Symbol oder Menü oder eine Tastenkombination gestartet werden.

¹ Der Vollständigkeit halber: wenn .bash_profile nicht existiert, versucht die Bash auch .bash_login, bevor sie auf .profile zurückgreift. Vergessen Sie ruhig, dass es existiert.

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

Aus diesem Kurzartikel

Laut der Bash-Manpage wird .bash_profile für Login-Shells ausgeführt, während .bashrc für interaktive Nicht-Login-Shells ausgeführt wird.

Was ist eine Login- oder Non-Login-Shell?

Wenn Sie sich über die Konsole anmelden (z. B.: Benutzername und Passwort eingeben), entweder physisch an der Maschine beim Booten oder aus der Ferne über ssh: .bash_profile wird ausgeführt, um Dinge vor der anfänglichen Eingabeaufforderung zu konfigurieren.

Wenn Sie sich aber bereits an Ihrem Rechner angemeldet haben und ein neues Terminalfenster (xterm) innerhalb von Gnome oder KDE öffnen, dann wird .bashrc vor der Eingabeaufforderung des Fensters ausgeführt. .bashrc wird auch ausgeführt, wenn Sie eine neue Bash-Instanz starten, indem Sie /bin/bash in ein Terminal eingeben.

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

In den alten Zeiten, als Pseudo-Ty’s noch keine Pseudo-Ty’s waren und tatsächlich, nun ja, getippt wurde und UNIXe von Modems angesprochen wurden, die so langsam waren, dass man jeden Buchstaben auf dem Bildschirm sehen konnte, war Effizienz das A und O. Um die Effizienz ein wenig zu steigern, gab es das Konzept eines Hauptanmeldefensters und der anderen Fenster, die man für die eigentliche Arbeit verwendete. In Ihrem Hauptfenster würden Sie gerne Benachrichtigungen über neue Mails erhalten und möglicherweise einige andere Programme im Hintergrund laufen lassen.

Um dies zu unterstützen, gab es in den Shells eine Datei .profile speziell für “Login-Shells”. Diese würde das Besondere tun, sobald eine Sitzung aufgebaut ist. Die Bash hat dies etwas erweitert, so dass sie zuerst in .bash_profile nachschaut, bevor sie in .profile nachschaut. Auf diese Weise können Sie dort nur Bash-Sachen ablegen (damit sie nicht die Bourne-Shell usw. versauen, die ebenfalls in .profile nachschaut). Andere Shells, die sich nicht anmelden, würden einfach die rc-Datei, .bashrc (oder .kshrc, usw.) als Quelle angeben.

Das ist jetzt ein bisschen ein Anachronismus. Man meldet sich nicht in einer Hauptshell an, sondern in einem GUI-Fenstermanager. Es gibt kein Hauptfenster, das sich von irgendeinem anderen Fenster unterscheidet.

Mein Vorschlag - machen Sie sich keine Gedanken über diesen Unterschied, er basiert auf einem älteren Stil der Verwendung von Unix. Eliminieren Sie den Unterschied in Ihren Dateien. Der gesamte Inhalt von .bash_profile sollte sein:

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

Und schreiben Sie alles, was Sie tatsächlich einstellen wollen, in .bashrc

Denken Sie daran, dass .bashrc für alle Shells, interaktiv und nicht-interaktiv, gesourced wird. Sie können das Sourcen für nicht-interaktive Shells kurzschließen, indem Sie diesen Code an den Anfang von .bashrc setzen:

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

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

Werfen Sie einen Blick auf diesen ausgezeichneten Blogbeitrag von ShreevatsaR . Hier ist ein Auszug, aber gehen Sie zum Blogbeitrag, er enthält eine Erklärung für Begriffe wie “Login-Shell”, ein Flussdiagramm und eine ähnliche Tabelle für Zsh.

Für Bash funktionieren sie wie folgt. Lesen Sie die entsprechende Spalte ab. Führt A aus, dann B, dann C, usw. Das B1, B2, B3 bedeutet, dass nur die erste der gefundenen Dateien ausgeführt wird.

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

EIN BESSERER KOMMENTAR FÜR DEN KOPF VON /ETC/PROFILE

Aufbauend auf Flimms großartiger Antwort oben, habe ich diesen neuen Kommentar am Kopf meiner Debian- /etc/profile eingefügt, (Sie müssen ihn vielleicht für Ihre Distribution anpassen.):

# 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)

& Und diesen Hinweis am Kopf jeder der anderen Setup-Dateien, um darauf zu verweisen:

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

Erwähnenswert ist meiner Meinung nach, dass Debians /etc/profile standardmäßig /etc/bash.bashrc (wenn /etc/bash.bashrc existiert) einbindet. Also lesen Login-Skripte beide /etc-Dateien, während Nicht-Login nur bash.bashrc liest.

Außerdem ist zu beachten, dass /etc/bash.bashrc so eingestellt ist, dass sie nichts tut, wenn sie nicht interaktiv ausgeführt wird. Diese beiden Dateien sind also nur für interaktive Skripte gedacht.

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

Die Konfigurationslogik der bash selbst ist nicht wahnsinnig kompliziert und in anderen Antworten auf dieser Seite, auf serverfault und in vielen Blogs erklärt. Das Problem ist jedoch was die Linux-Distributionen aus der bash machen, ich meine die komplexen und verschiedenen Arten, wie sie die bash standardmäßig konfigurieren. http://mywiki.wooledge.org/DotFiles erwähnt einige dieser Macken kurz. Hier ist ein Beispiel-Trace auf Fedora 29, er zeigt, welche Dateien welche andere(n) Datei(en) quellen lassen und in welcher Reihenfolge für ein sehr einfaches Szenario: Fernverbindung mit ssh und dann Start einer anderen Subshell:

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

Fedoras komplexeste Logik ist in /etc/bashrc. Wie oben gesehen ist /etc/bashrc eine Datei, von der die Bash selbst nichts weiß, ich meine nicht direkt. Fedoras /etc/bashrc testet, ob:

  • es von einer Login-Shell aufgerufen wird,
  • es von einer interaktiven Shell aufgerufen wird,
  • es bereits von

aufgerufen wurde … und macht dann je nach dem völlig unterschiedliche Dinge.

Wenn Sie glauben, sich an den obigen Graphen erinnern zu können, dann ist das schade, denn er ist nicht annähernd ausreichend: Dieser Graph beschreibt nur ein Szenario, etwas andere Dinge passieren, wenn nicht-interaktive Skripte ausgeführt werden oder eine grafische Sitzung gestartet wird. Ich habe ~/.profile weggelassen. Ich habe bash_completion-Skripte weggelassen. Aus Gründen der Abwärtskompatibilität ändert sich das Verhalten der Bash, wenn man sie mit /bin/sh statt mit /bin/bash aufruft. Was ist mit zsh und anderen Shells? Und natürlich machen verschiedene Linux-Distributionen die Dinge anders, zum Beispiel Debian und Ubuntu kommen mit einer nicht standardisierten Version von bash, sie hat Debian-spezifische Anpassung(en). Es sucht insbesondere nach einer ungewöhnlichen Datei: /etc/bash.bashrc. Selbst wenn Sie bei einer einzigen Linux-Distribution bleiben, entwickelt sie sich wahrscheinlich mit der Zeit weiter. Warten Sie: wir haben noch nicht einmal macOS, FreeBSD,… berührt. Lassen Sie uns zum Schluss noch einen Gedanken an die Benutzer verschwenden, die mit den noch kreativeren Methoden feststecken, mit denen ihre Admins das System konfiguriert haben, das sie benutzen müssen.

Wie der nicht enden wollende Strom von Diskussionen zu diesem Thema zeigt, ist das ein hoffnungsloser Fall. Solange Sie nur neue Werte hinzufügen wollen, reicht ein wenig “Versuch und Irrtum” in der Regel aus. Der eigentliche Spaß beginnt, wenn Sie in einer (Benutzer-)Datei etwas verändern wollen, was in einer anderen (in /etc) bereits definiert ist. Dann müssen Sie sich darauf einstellen, einige Zeit mit der Entwicklung einer Lösung zu verbringen, die niemals portabel sein wird.

Für ein letztes bisschen Spaß ist hier der “Quellgraf” für das gleiche, einfache Szenario auf Clear Linux, Stand 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