Frage Unterschied zwischen .bashrc und .bash_profile


Was ist der Unterschied zwischen .bashrc und .bash_profile und welchen sollte ich benutzen?


401
2017-09-02 14:40


Ursprung


Siehe auch diese ähnliche Frage an ubuntu.stackexchange.com/questions/1528/bashrc-or-bash-profile - Stefan Lasiewski
Wenn Sie eine umfassendere Erklärung benötigen, die auch beinhaltet .profileSehen Sie sich diese Frage an: superuser.com/questions/789448/ ... - Flimm
Diese Antwort deckt auch einige Aspekte ab stackoverflow.com/questions/415403/ ... - Sergey Voronezhskiy


Antworten:


Üblicherweise startet das System bei der Anmeldung an einem Unix-System ein Programm für Sie. Dieses Programm ist eine Shell, d. H. Ein Programm, das entworfen wurde, um andere Programme zu starten. Es ist eine Kommandozeilen-Shell: Sie starten ein anderes Programm, indem Sie seinen Namen eingeben. Die Standard-Shell, eine Bourne-Shell, liest Befehle aus ~/.profile wenn es als Login-Shell aufgerufen wird.

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

Sie können eine Shell jederzeit direkt aufrufen, z. B. durch Starten eines Terminalemulators in einer GUI-Umgebung. Wenn die Shell keine Login-Shell ist, wird sie nicht gelesen ~/.profile. Wenn Sie bash als interaktive Shell starten (d. H. Kein Skript ausführen), wird es gelesen ~/.bashrc (Außer wenn es als Login-Shell aufgerufen wird, liest es nur ~/.bash_profile oder ~/.profile.

Deshalb:

  • ~/.profile ist der Platz, um Dinge, die für Ihre gesamte Sitzung gelten, wie z. B. Programme, die Sie bei der Anmeldung starten möchten (aber keine grafischen Programme, sie gehen in eine andere Datei), und Definitionen der Umgebungsvariablen zu platzieren.

  • ~/.bashrc ist der Platz, um Sachen zu platzieren, die nur für bash selbst gelten, wie zum Beispiel Alias- und Funktionsdefinitionen, Shell-Optionen und Prompt-Einstellungen. (Du könntest auch Tastenbindungen dort platzieren, aber für Bash gehen sie normalerweise hinein ~/.inputrc.)

  • ~/.bash_profile kann anstelle von verwendet werden ~/.profile, aber es wird nur von bash gelesen, nicht von irgendeiner anderen Shell. (Dies ist vor allem dann von Bedeutung, wenn Sie möchten, dass Ihre Initialisierungsdateien auf mehreren Rechnern funktionieren und Ihre Login-Shell auf allen nicht bash ist.) Dies ist ein logischer Platz zum Einbinden ~/.bashrc wenn die Shell interaktiv ist. Ich empfehle folgende Inhalte in ~/.bash_profile:

    if [ -r ~/.profile ]; then . ~/.profile; fi
    case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
    

Auf modernen Units gibt es eine zusätzliche Komplikation in Bezug auf ~/.profile. Wenn Sie sich in einer grafischen Umgebung anmelden (dh wenn das Programm, in dem Sie Ihr Kennwort eingeben, im Grafikmodus ausgeführt wird), erhalten Sie nicht automatisch eine Login-Shell, die liest ~/.profile. Abhängig von dem grafischen Anmeldeprogramm, dem Fenstermanager oder der Desktop-Umgebung, die Sie anschließend ausführen, und davon, wie Ihre Distribution diese Programme konfiguriert hat, wird Ihr ~/.profile kann oder darf nicht gelesen werden. Wenn dies nicht der Fall ist, gibt es normalerweise einen anderen Ort, an dem Sie Umgebungsvariablen und Programme definieren können, die beim Anmelden gestartet werden. Leider gibt es keinen Standardstandort.

Beachten Sie, dass Sie hier und da Empfehlungen finden können, in die Definitionen für Umgebungsvariablen eingefügt werden ~/.bashrc oder starten Sie immer Login-Shells in Terminals. Beide sind schlechte Ideen. Das häufigste Problem mit einer dieser Ideen ist, dass Ihre Umgebungsvariablen nur in Programmen gesetzt werden, die über das Terminal gestartet werden, nicht in Programmen, die direkt mit einem Symbol oder Menü oder einer Tastenkombination gestartet wurden.

¹  Zur Vollständigkeit, auf Anfrage: if .bash_profile existiert nicht, bash versucht es auch .bash_loginbevor wir zurückfallen .profile. Fühlen Sie sich frei zu vergessen, dass es existiert.  


471
2017-09-02 19:23



+1 für einen guten Beitrag. ALSO vielen Dank für das Hinzufügen von Abschnitt über "Login-Grafik vs Login-Shell" ... Ich hatte das Problem, wo ich dachte, ~ /. Profile würde immer für grafische / Shell ausführen ... aber es wird nicht ausgeführt, wenn der Benutzer sich anmeldet über grafische Anmeldung. Danke, dass du dieses Geheimnis gelöst hast. - Trevor Boyd Smith
@Gilles: Kannst du anhand von Beispielen genauer erklären, warum es in jedem Terminal eine schlechte Idee ist, eine Login-Shell zu betreiben? Ist das nur ein Problem mit Desktop-Linux? (Ich nehme an, dass auf OS X Terminal jedes Mal eine Login-Shell läuft und ich nie irgendwelche Nebenwirkungen bemerkt habe (obwohl ich normalerweise iTerm verwende), aber dann kann ich mir nicht viele Umgebungsvariablen vorstellen, die außerhalb von mir liegen ein Terminal. (Vielleicht HTTP_PROXY?)) - iconoclast
@Brandon Wenn Sie in jedem Terminal eine Login-Shell ausführen, werden die von der Umgebung bereitgestellten Umgebungsvariablen überschrieben. In alltäglichen Situationen kann man damit durchkommen, aber es wird Sie früher oder später beißen, wenn Sie verschiedene Variablen in einem Terminal einrichten wollen (um beispielsweise eine andere Version eines Programms auszuprobieren): a Die Login-Shell würde Ihre lokalen Einstellungen außer Kraft setzen. - Gilles
Die Aussage ~/.bash_profile kann anstelle von verwendet werden ~/.profile, aber Sie müssen auch einschließen ~/.bashrc wenn die Shell interaktiv ist. ist irreführend, da es sich um orthogonale Probleme handelt. Egal, ob Sie verwenden ~/.bash_profile oder ~/.profile du musst einschließen ~/.bashrc in dem, den Sie verwenden, wenn Sie wollen, dass Einstellungen von dort in der Login-Shell wirksam werden. - Piotr Dobrogost
@Gilles Sicher, aber die Art und Weise, wie der Satz in der Antwort formuliert wird, deutet darauf hin, dass die Notwendigkeit enthalten ist ~/.bashrc hat etwas mit der Wahl zu tun ~/.bash_profile Anstatt von ~/.profile was nicht wahr ist. Wenn jemand etwas einschließt ~/.bashrc in jeder Art von Skript wird bei der Anmeldung Zeit (hier ist es entweder ~/.bash_profile oder ~/.profile) weil er Einstellungen von will ~/.bashrc auf die Login-Shell angewendet werden, so wie sie auf Nicht-Login-Shell angewendet werden. - Piotr Dobrogost


Davon kurzer Artikel

Laut der Bash-Man-Seite,   .bash_profile wird für die Anmeldung ausgeführt   Shells, während. Bashrc für ausgeführt wird   interaktive Nicht-Login-Shells.

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

Wenn Sie sich anmelden (zB: Benutzername und   Passwort) über die Konsole   physisch an der Maschine sitzen   Booten, oder remote über ssh:   .bash_profile wird zur Konfiguration ausgeführt   Dinge vor dem ersten Befehl   prompt.

Aber wenn Sie sich bereits angemeldet haben   Ihre Maschine und öffnen Sie ein neues Terminal   Fenster (xterm) in Gnome oder KDE,   dann wird .bashrc vor dem ausgeführt   Fenster Eingabeaufforderung. .bashrc ist auch   Ausführen, wenn Sie eine neue Bash-Instanz starten   indem Sie / bin / bash in ein Terminal eingeben.


50
2017-09-02 14:54



Geringfügige Updates: "Executed" ist wahrscheinlich ein leicht irreführender Begriff, beide stammen aus Quellen. Ausgeführte Sounds, wie es als Skript ausgeführt wird, fork / exec yadda yadda. Es wird im Kontext der aktuellen Shell ausgeführt. Noch wichtiger ist, dass .bashrc viel häufiger ausgeführt wird. Es wird bei jedem Bash-Script-Lauf ausgeführt, und auch wenn Sie kein .bash_profile haben. Abhängig davon, wie Sie Ihre xterms einrichten, können Sie auch eine Shell erstellen, die .bash_profile bereitstellt - Rich Homolka


Früher, als Pseudo-Tty's nicht Pseudo waren und tatsächlich, gut, getippt, und Unixe von Modems so langsam zugegriffen wurden, dass man jeden Buchstaben auf dem Bildschirm sehen konnte, war die Effizienz von größter Bedeutung. Um die Effizienz etwas zu verbessern, hatten Sie das Konzept eines Hauptanmeldungsfensters und anderer Fenster, mit denen Sie tatsächlich gearbeitet haben. In Ihrem Hauptfenster möchten Sie Benachrichtigungen zu jeder neuen E-Mail, möglicherweise führen Sie einige andere Programme im Hintergrund.

Um dies zu unterstützen, haben Shells eine Datei erstellt .profile speziell auf 'Login Shells'. Dies würde das Besondere, einmal eine Sitzung einrichten. Bash hat dies etwas ausgedehnt, um .bash_profile zuerst vor .profile zu sehen, auf diese Weise könntest du bash nur Dinge hineinbringen (damit sie die Bourne-Shell, etc., die auch auf .profile geschaut hat) nicht vermasseln. Andere Shells, die sich nicht anmelden, würden nur die RC-Datei, .bashrc (oder .kshrc usw.), bereitstellen.

Das ist jetzt ein bisschen ein Anachronismus. Sie loggen sich nicht so oft in eine Haupt-Shell ein, wie Sie sich bei einem GUI-Window-Manager anmelden. Es gibt kein Hauptfenster, das sich von anderen Fenstern unterscheidet.

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

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

Und setzen Sie alles, was Sie eigentlich in .bashrc einstellen möchten

Denken Sie daran, dass .bashrc für alle interaktiven und nicht interaktiven Shells bereitgestellt wird. Sie können das Sourcing für nicht interaktive Shells kurzschließen, indem Sie diesen Code in der Nähe von .bashrc platzieren:

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


34
2017-09-02 18:10



Das ist eine schlechte Idee meine Antwort. Insbesondere werden Ihre Umgebungsvariablen nur in Programmen festgelegt, die über das Terminal gestartet werden, nicht in Programmen, die direkt mit einem Symbol oder Menü oder einer Tastenkombination gestartet wurden. - Gilles
@Gilles Ich verstehe nicht, warum Sie das behaupten. Mit .$HOME/.bashrc wie Rich oben gezeigt hat, Einstellungen in .bashrc wird in Login-Shells und somit auch in der Desktop-Umgebung verfügbar sein. Zum Beispiel, auf meinem Fedora-System, gnome-session wird als gestartet -$SHELL -c gnome-session, damit .profile ist gelesen. - Mikel
@PiotrDobrogost Oh, ja, es gibt ein anderes Problem mit Richs Antwort. Einschließlich .bashrc im .profile funktioniert normalerweise nicht, weil .profile kann durch ausgeführt werden /bin/sh und nicht bash (z. B. auf Ubuntu für eine grafische Anmeldung standardmäßig), und diese Shell ist möglicherweise nicht interaktiv (z. B. für eine grafische Anmeldung). - Gilles
@Gilles re: "inklusive .bashrc in .profile" ist überhaupt nicht das, was empfohlen wurde (im Gegenteil, tatsächlich). Entweder wurde die Antwort bearbeitet (es erscheint nicht so), oder Ihre Kommentare stimmen nicht mit dem überein, was gesagt wird. - michael
Im Allgemeinen +1, aber ich würde hinzufügen, die Empfehlung zu "Kurzschluss ... für nicht interaktive Shells" ("in der Nähe der Spitze von. Bashrc: [[ $- != *i* ]] && return") Ich mag einige von meinen .bashrc auch für nicht interaktive Shells ausgeführt werden, speziell um env vars beim Ausgeben festzulegen ssh hostname {command}, damit die Remote-Befehle korrekt ausgeführt werden (obwohl die Shell nicht interaktiv ist). Aber andere Einstellungen später in .bashrc sollte ignoriert werden. Normalerweise suche ich nach TERM = dumm und / oder unset und dann früh raus. - michael


Schau dir das an ausgezeichneter Blog-Beitrag von ShreevatsaR. Hier ist ein Auszug, aber gehen Sie zum Blog-Post, es 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 nach. Führt A, dann B, dann C usw. aus. 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      |           |      |
+----------------+-----------+-----------+------+

14
2017-07-13 08:53



Anstatt die gleiche Antwort auf mehrere Fragen zu schreiben, ist es besser, wenn Sie Ihre Antwort auf die spezifischen Bedürfnisse des Fragestellers zuschneiden können. Wenn die Antwort für beide Fragen identisch ist, sollten Sie eine einzige Antwort und Abstimmung abgeben, um die anderen Fragen als Duplikate des Originals zu schließen. - Mokubai♦
@Mokubai Die andere Frage wurde bereits als Duplikat markiert. - Flimm
@ElipticalView: per set, um nichts zu tun, beziehen Sie sich auf die Zeile: [ -z "$PS1" ] && return? Die Tabelle in meiner Antwort gibt die Liste der von Bash ausgeführten Skripts unabhängig vom Inhalt der Skripts an, wenn das Skript selbst über die Zeile verfügt [ -z "$PS1" ] && returnDas würde natürlich in Kraft treten, aber ich glaube nicht, dass ich den Tisch wechseln sollte. - Flimm


Ein besseres Kommentar für den Kopf von / ETC / Profil

Aufbauend auf Flimms großer Antwort oben habe ich diesen neuen Kommentar an der Spitze meines Debian / etc / profile eingefügt. (Sie müssen es möglicherweise 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 diese Notiz an der Spitze jeder der anderen Setup-Dateien, um darauf Bezug zu nehmen:

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

Bemerkenswert ist, dass Debian / etc / profile standardmäßig Quellen (includes) /etc/bash.bashrc (das ist, wenn /etc/bash.bashrc existiert). So lesen Login-Skripte beide / etc-Dateien, während Nicht-Login nur bash.bashrc liest.

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


3
2017-10-18 18:13