Was ist der Unterschied zwischen .bashrc
und .bash_profile
und welches soll ich verwenden?
.profile
, werfen Sie einen Blick auf diese Frage: superuser.com/questions/789448/…
Was ist der Unterschied zwischen .bashrc
und .bash_profile
und welches soll ich verwenden?
.profile
, werfen Sie einen Blick auf diese Frage: superuser.com/questions/789448/…
Antworten:
Wenn Sie sich in ein Unix-System einloggen, startet das System normalerweise ein Programm für Sie. Dieses Programm ist eine Shell, dh 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, ~/.profile
wenn sie als Anmeldeshell aufgerufen wird.
Bash ist eine Bourne-ähnliche Shell. Es liest Befehle ab dem ~/.bash_profile
Zeitpunkt, an dem es als Anmeldeshell aufgerufen wird, und wenn diese Datei nicht existiert¹, wird ~/.profile
stattdessen versucht, sie zu lesen .
Sie können eine Shell jederzeit direkt aufrufen, indem Sie beispielsweise einen Terminalemulator in einer GUI-Umgebung starten. Wenn die Shell keine Anmeldeshell ist, wird sie nicht gelesen ~/.profile
. Wenn Sie bash als interaktive Shell starten (dh kein Skript ausführen), liest es ~/.bashrc
(außer wenn es als Anmeldeshell aufgerufen wird ), dann liest es nur ~/.bash_profile
oder ~/.profile
.
Deshalb:
~/.profile
Hier können Sie Informationen ablegen, die für Ihre gesamte Sitzung gelten, z. B. Programme, die Sie beim Anmelden starten möchten (nicht jedoch grafische Programme, die in eine andere Datei verschoben werden), und Umgebungsvariablendefinitionen.
~/.bashrc
ist der Ort, an dem Dinge abgelegt werden, die nur für Bash selbst gelten, wie Alias- und Funktionsdefinitionen, Shell-Optionen und Einstellungen für Eingabeaufforderungen. (Sie können dort auch Tastenkombinationen einfügen, aber für Bashs werden sie normalerweise verwendet ~/.inputrc
.)
~/.bash_profile
kann anstelle von verwendet werden ~/.profile
, wird aber nur von bash gelesen, nicht von einer anderen Shell. (Dies ist hauptsächlich dann von Belang, wenn Sie möchten, dass Ihre Initialisierungsdateien auf mehreren Computern ausgeführt werden und Ihre Anmeldeshell nicht alle von ihnen unterstützt.) Dies ist eine logische Angabe, ~/.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
Bei modernen Unices tritt eine zusätzliche Komplikation auf ~/.profile
. Wenn Sie sich in einer grafischen Umgebung anmelden (d. H., Wenn das Programm, in das Sie Ihr Kennwort eingeben, im Grafikmodus ausgeführt wird), wird nicht automatisch eine Anmeldeshell angezeigt, die den Text liest ~/.profile
. Abhängig vom grafischen Anmeldeprogramm, vom Windows-Manager oder der Desktop-Umgebung, die Sie anschließend ausführen, und davon, wie Ihre Distribution diese Programme konfiguriert hat, können Sie ~/.profile
möglicherweise gelesen werden oder nicht. Wenn dies nicht der Fall ist, können Sie normalerweise an einer anderen Stelle Umgebungsvariablen und Programme definieren, die beim Anmelden gestartet werden sollen. Es gibt jedoch leider keinen Standardspeicherort.
Beachten Sie, dass hier und da möglicherweise Empfehlungen angezeigt werden, Umgebungsvariablendefinitionen einzufügen ~/.bashrc
oder Anmeldeshells immer in Terminals zu starten. Beides sind schlechte Ideen. Das häufigste Problem bei diesen beiden Ideen ist, dass Ihre Umgebungsvariablen nur in Programmen festgelegt werden, die über das Terminal gestartet werden, nicht in Programmen, die direkt mit einem Symbol oder einem Menü oder einer Tastenkombination gestartet werden.
¹ Der Vollständigkeit .bash_profile
halber auf Anfrage: Falls nicht vorhanden, versucht bash es auch, .bash_login
bevor auf zurückgegriffen wird .profile
. Fühlen Sie sich frei zu vergessen, dass es existiert.
~/.bash_profile
kann anstelle von verwendet werden ~/.profile
, Sie müssen jedoch auch angeben, ~/.bashrc
ob die Shell interaktiv ist. ist irreführend, da dies orthogonale Probleme sind. Egal, ob Sie verwenden ~/.bash_profile
oder ob Sie in die von Ihnen verwendete ~/.profile
einbeziehen müssen, ~/.bashrc
wenn die Einstellungen von dort in der Anmeldeshell wirksam werden sollen.
~/.bashrc
etwas mit der Auswahl zu tun hat, ~/.bash_profile
anstatt dass ~/.profile
dies nicht wahr ist. Wenn jemand ein ~/.bashrc
Skript in ein Skript einbezieht, das zur Anmeldezeit bezogen wird (hier entweder ~/.bash_profile
oder ~/.profile
), möchte er, dass die Einstellungen ~/.bashrc
auf die Anmelde-Shell genauso angewendet werden, wie sie auf Nicht-Anmelde-Shell angewendet werden.
Aus diesem kurzen Artikel
Der Bash-Manpage zufolge wird .bash_profile für Anmeldeshells ausgeführt, während .bashrc für interaktive Shells ohne Anmeldung ausgeführt wird.
Was ist eine Login- oder Nicht-Login-Shell?
Wenn Sie sich über die Konsole anmelden (z. B. Benutzername und Kennwort eingeben), entweder während des Bootvorgangs physisch am Computer oder remote über ssh: .bash_profile, werden die Dinge vor der ersten Eingabeaufforderung konfiguriert.
Wenn Sie sich jedoch bereits bei Ihrem Computer angemeldet haben und ein neues Terminalfenster (xterm) in Gnome oder KDE öffnen, wird .bashrc vor der Eingabeaufforderung des Fensters ausgeführt. .bashrc wird auch ausgeführt, wenn Sie eine neue Bash-Instanz durch Eingabe von / bin / bash in einem Terminal starten.
Früher, als Pseudo-Tty nicht pseudo und eigentlich gut getippt waren und Modems so langsam auf UNIXes zugegriffen haben, dass Sie sehen konnten, wie jeder Buchstabe auf Ihrem Bildschirm gedruckt wurde, war Effizienz von höchster Wichtigkeit. Um die Effizienz zu verbessern, hatten Sie das Konzept eines Hauptanmeldefensters und aller anderen Fenster, die Sie früher verwendet haben. In Ihrem Hauptfenster möchten Sie Benachrichtigungen zu neuen E-Mails erhalten und möglicherweise andere Programme im Hintergrund ausführen.
Um dies zu unterstützen, haben Shells eine Datei .profile
speziell für "Login-Shells" bereitgestellt. Dies würde das Besondere tun, einmal eine Sitzung einzurichten. Bash hat dies etwas erweitert, um zuerst nach .bash_profile und dann nach .profile zu suchen. Auf diese Weise können Sie nur Bash-Elemente einfügen (damit die Bourne-Shell usw., die sich auch mit .profile befasst, nicht beschädigt wird). Andere Shells, die sich nicht anmelden, geben nur die RC-Datei .bashrc (oder .kshrc usw.) aus.
Das ist jetzt ein bisschen wie ein Anachronismus. Sie melden sich nicht so oft bei einer Haupt-Shell an wie bei einem GUI-Fenstermanager. Es gibt kein anderes Hauptfenster als jedes andere.
Mein Vorschlag - mach dir keine Sorgen um diesen Unterschied, er basiert auf einem älteren Unix-Stil. 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 wirklich wollen, in .bashrc
Denken Sie daran, dass .bashrc für alle Shells (interaktiv und nicht interaktiv) bereitgestellt wird. Sie können das Sourcing für nicht interaktive Shells kurzschließen, indem Sie diesen Code oben in .bashrc einfügen:
[[ $- != *i* ]] && return
.$HOME/.bashrc
als Rich oben zeigte, in Einstellungen .bashrc
werden in Login - Shells und damit die Desktop - Umgebung als auch zur Verfügung. Zum Beispiel auf meinem Fedora - System gnome-session
wird gestartet, -$SHELL -c gnome-session
so .profile
gelesen wird.
.bashrc
in .profile
funktioniert normalerweise nicht, da .profile
es von /bin/sh
und ohne Bash ausgeführt werden kann (z. B. unter Ubuntu für eine grafische Anmeldung standardmäßig) und diese Shell möglicherweise nicht interaktiv ist (z. B. für eine grafische Anmeldung).
[[ $- != *i* ]] && return
"); Ich möchte, dass einige von meinen .bashrc
auch für nicht interaktive Shells ausgeführt werden, insbesondere um env vars bei der Ausgabe festzulegen ssh hostname {command}
, damit die Remote-Befehle korrekt ausgeführt werden (obwohl die Shell nicht interaktiv ist). Andere Einstellungen später .bashrc
sollten jedoch ignoriert werden. Normalerweise überprüfe ich, ob TERM = dumm und / oder nicht gesetzt ist, und steige dann früh aus.
Schauen Sie sich diesen ausgezeichneten Blog-Beitrag von ShreevatsaR an . Hier ist ein Auszug, aber gehen Sie zum Blog-Beitrag, der eine Erklärung für Begriffe wie "Login-Shell", ein Flussdiagramm und eine ähnliche Tabelle für Zsh enthält.
Für Bash arbeiten sie wie folgt. Lesen Sie die entsprechende Spalte. 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 | | |
+----------------+-----------+-----------+------+
[ -z "$PS1" ] && return
? Die Tabelle in meiner Antwort enthält die Liste der von Bash ausgeführten Skripte, unabhängig vom Inhalt der Skripte. Wenn das Skript selbst die Zeile enthält [ -z "$PS1" ] && return
, würde dies natürlich wirksam, aber ich denke nicht, dass dies bedeuten sollte, dass ich die ändern sollte Tabelle.
EIN BESSERER KOMMENTAR FÜR DEN KOPF VON / ETC / PROFILE
Aufbauend auf der großartigen Antwort von Flimm oben habe ich diesen neuen Kommentar an der Spitze meines Debian / etc / -Profils eingefügt (möglicherweise müssen Sie ihn 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 dieser 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
Bemerkenswert finde ich, dass Debians / etc / profile standardmäßig /etc/bash.bashrc (also /etc/bash.bashrc) enthält. So lesen Anmeldeskripte beide / etc-Dateien, während Nicht-Anmeldeskripte nur bash.bashrc lesen.
Zu beachten ist auch, dass /etc/bash.bashrc so eingestellt ist, dass es nichts tut, wenn es nicht interaktiv ausgeführt wird. Diese beiden Dateien sind also nur für interaktive Skripte gedacht.
Die Konfigurationslogik von bash selbst ist nicht verrückt kompliziert und wird in anderen Antworten auf dieser Seite, auf serverfault und in vielen Blogs erklärt. Das Problem ist jedoch, was die Linux-Distributionen aus bash machen , ich meine die komplexen und verschiedenen Arten, wie sie bash standardmäßig konfigurieren. http://mywiki.wooledge.org/DotFiles erwähnt einige dieser Macken kurz. Hier ist ein Beispiel-Trace für Fedora 29, der zeigt, welche Dateien welche anderen Dateien in welcher Reihenfolge als Quelle haben: Remote-Verbindung mit ssh und Starten einer weiteren 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 zu sehen /etc/bashrc
ist, weiß eine Datei Bash selbst nichts, ich meine nicht direkt. Fedoras /etc/bashrc
Tests, ob:
... und macht dann ganz andere Sachen je nachdem.
Wenn Sie denken, dass Sie sich an das obige Diagramm erinnern können, ist dies zu schade, da es bei weitem nicht ausreicht: Dieses Diagramm beschreibt nur ein einziges Szenario. Beim Ausführen nicht interaktiver Skripte oder Starten einer grafischen Sitzung treten geringfügig andere Probleme auf. Ich habe weggelassen ~/.profile
. Ich habe bash_completion
Skripte weggelassen . Aus Gründen der Abwärtskompatibilität wird durch Aufrufen von bash as /bin/sh
statt /bin/bash
dessen Verhalten geändert. Was ist mit zsh und anderen Shells? Und natürlich machen verschiedene Linux-Distributionen die Dinge anders, zum Beispiel werden Debian und Ubuntu mit einer nicht-standardmäßigen Version von bas h ausgeliefert, es hat Debian-spezifische Anpassungen. Es sucht insbesondere nach einer ungewöhnlichen Datei:/etc/bash.bashrc
. Selbst wenn Sie sich an eine einzelne Linux-Distribution halten, entwickelt sich diese wahrscheinlich im Laufe der Zeit weiter. Warten Sie: Wir haben noch nicht einmal MacOS, FreeBSD, ... angerührt. Lassen Sie uns zum Schluss einen Gedanken über die noch kreativeren Methoden machen, mit denen die Administratoren das zu verwendende System konfiguriert haben.
Wie der endlose Strom von Diskussionen zu diesem Thema zeigt, ist es eine verlorene Sache. Solange Sie nur neue Werte hinzufügen möchten, ist ein gewisser "Versuch und Irrtum" in der Regel ausreichend. Der wahre Spaß beginnt, wenn Sie in einer (Benutzer-) Datei etwas ändern möchten, das bereits in einer anderen (in / etc) definiert ist. Stellen Sie sich dann darauf ein, einige Zeit mit der Entwicklung einer Lösung zu verbringen, die niemals portabel sein wird.
Für ein letztes bisschen Spaß ist hier das "Quelldiagramm" für das gleiche, einfache Szenario unter Clear Linux ab 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